如何使用scatter_kws自定义pairplot中的标记样式

huangapple go评论99阅读模式
英文:

How to customize the marker style in a pairplot using scatter_kws

问题

I understand your request, and I will provide the translated code without the code comments and explanations. Here's the translated code:

  1. import seaborn as sns
  2. import matplotlib.pyplot as plt
  3. iris = sns.load_dataset("iris")
  4. marker_styles = ['o', 's', 'D']
  5. species_to_marker = {'setosa': 'o', 'versicolor': 's', 'virginica': 'D'}
  6. iris['markers'] = iris['species'].map(species_to_marker)
  7. scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species']}
  8. sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
  9. hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)
  10. plt.show()

If you have any further questions or need assistance with specific parts of the code, please feel free to ask.

英文:

I can successfully specify a variable to use as the marker style and a different variable to use as the color for a seaborne pairplot. However I cannot override the default marker styles with my own.

Here is a minimal working example of what I can do when I define the style of the iris dataset to 'species' and get a nice pairplot with different marker styles. When I comment out the working line of code with my new line of code to change the style of marker to the one I created it gives an error.

  1. import seaborn as sns
  2. import matplotlib.pyplot as plt
  3. # Load example dataset
  4. iris = sns.load_dataset("iris")
  5. # Define marker styles "Circle", "Square", "Diamond"
  6. marker_styles = ['o', 's', 'D']
  7. # Map species to marker styles (read again as "Circle", "Square", "Diamond")
  8. species_to_marker = {'setosa': 'o', 'versicolor': 's', 'virginica': 'D'}
  9. iris['markers'] = iris['species'].map(species_to_marker)
  10. # Pass marker style column to scatterplot arguments
  11. # This sort of works: at least maps the variable to the default marker style:
  12. scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species']} # 'style' assigns DEFAULT markers which can be interpreted as "circle, x, square"
  13. # This doesn't work: I want to use my non-default markers that are mapped to the variable:
  14. # scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species'], 'marker': iris['markers']} # I want to overwrite marker-style with my custom defined marker_styles now mapped in variable iris['markers']
  15. # Pass scatterplot arguments to pairplot, only plot lower-left-triangle of pairs
  16. sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
  17. hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)
  18. # Display the plot
  19. plt.show()

When I specify 'markers' to scatterplot arguments to assign iris['markers'] with the following replacement code

  1. scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species'], 'marker': iris['markers']}

I get TypeError: unhashable type: 'Series', here it is expanded out:

  1. TypeError Traceback (most recent call last)
  2. <ipython-input-600-3640788f836b> in <cell line: 21>()
  3. 19
  4. 20 # Pass scatterplot arguments to pairplot
  5. ---> 21 sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
  6. 22 hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)
  7. 23
  8. 8 frames
  9. /usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in pairplot(data, hue, hue_order, palette, vars, x_vars, y_vars, kind, diag_kind, markers, height, aspect, corner, dropna, plot_kws, diag_kws, grid_kws, size)
  10. 2156 if kind == "scatter":
  11. 2157 from .relational import scatterplot # Avoid circular import
  12. -> 2158 plotter(scatterplot, **plot_kws)
  13. 2159 elif kind == "reg":
  14. 2160 from .regression import regplot # Avoid circular import
  15. /usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in map_offdiag(self, func, **kwargs)
  16. 1417 """
  17. 1418 if self.square_grid:
  18. -> 1419 self.map_lower(func, **kwargs)
  19. 1420 if not self._corner:
  20. 1421 self.map_upper(func, **kwargs)
  21. /usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in map_lower(self, func, **kwargs)
  22. 1387 """
  23. 1388 indices = zip(*np.tril_indices_from(self.axes, -1))
  24. -> 1389 self._map_bivariate(func, indices, **kwargs)
  25. 1390 return self
  26. 1391
  27. /usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in _map_bivariate(self, func, indices, **kwargs)
  28. 1566 if ax is None: # i.e. we are in corner mode
  29. 1567 continue
  30. -> 1568 self._plot_bivariate(x_var, y_var, ax, func, **kws)
  31. 1569 self._add_axis_labels()
  32. 1570
  33. /usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in _plot_bivariate(self, x_var, y_var, ax, func, **kwargs)
  34. 1607 "hue": hue, "hue_order": self._hue_order, "palette": self._orig_palette,
  35. 1608 })
  36. -> 1609 func(x=x, y=y, **kwargs)
  37. 1610
  38. 1611 self._update_legend_data(ax)
  39. /usr/local/lib/python3.10/dist-packages/seaborn/relational.py in scatterplot(data, x, y, hue, size, style, palette, hue_order, hue_norm, sizes, size_order, size_norm, markers, style_order, legend, ax, **kwargs)
  40. 759 kwargs["color"] = _default_color(ax.scatter, hue, color, kwargs)
  41. 760
  42. --> 761 p.plot(ax, kwargs)
  43. 762
  44. 763 return ax
  45. /usr/local/lib/python3.10/dist-packages/seaborn/relational.py in plot(self, ax, kws)
  46. 566 if not isinstance(m, mpl.markers.MarkerStyle):
  47. 567 # TODO in more recent matplotlib (which?) can pass a MarkerStyle here
  48. --> 568 m = mpl.markers.MarkerStyle(m)
  49. 569 if m.is_filled():
  50. 570 kws.setdefault("edgecolor", "w")
  51. /usr/local/lib/python3.10/dist-packages/matplotlib/markers.py in __init__(self, marker, fillstyle, transform, capstyle, joinstyle)
  52. 270 "%(since)s; support will be removed %(removal)s. Use "
  53. 271 "MarkerStyle('') to construct an empty MarkerStyle.")
  54. --> 272 self._set_marker(marker)
  55. 273
  56. 274 __init__.__signature__ = inspect.signature( # Only for deprecation period.
  57. /usr/local/lib/python3.10/dist-packages/matplotlib/markers.py in _set_marker(self, marker)
  58. 349 self._marker_function = self._set_tuple_marker
  59. 350 elif (not isinstance(marker, (np.ndarray, list)) and
  60. --> 351 marker in self.markers):
  61. 352 self._marker_function = getattr(
  62. 353 self, '_set_' + self.markers[marker])
  63. TypeError: unhashable type: 'Series'

I tried to fix by converting the 'marker' column to a list by using the following code:

  1. scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species'], 'marker': iris['markers'].tolist()}

but this raises the following ValueError:

  1. ValueError: Unrecognized marker style ['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D']

It seems it cannot match to just one-value in the column iris['markers'] and is matching to the entire series or the entire list.

I am using the following libraries in Google Colab:

Seaborne version: 0.12.2
Matplotlib version: 3.7.1
Python version: 3.10.11 (main, Apr 5 2023, 14:15:10) [GCC 9.4.0]

答案1

得分: 1

我相信错误在于需要使用复数的 'markers' 而不是单数的 'marker' 在 scatter 关键词字典中。我仍然很好奇是否有人能改进这个答案。

  1. import seaborn as sns
  2. import matplotlib.pyplot as plt
  3. # 加载示例数据集
  4. iris = sns.load_dataset("iris")
  5. # 定义标记样式
  6. marker_styles = ['o', 's', 'D']
  7. # 将物种映射到标记样式
  8. species_to_marker = {'setosa': 'o', 'versicolor': 's', 'virginica': 'D'}
  9. # 我相信错误在于使用 'marker': 而不是 'markers':
  10. # 将标记样式列传递给散点图参数
  11. scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species'], 'markers': species_to_marker}
  12. # 将散点图参数传递给 pairplot
  13. sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
  14. hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)
  15. # 显示图表
  16. plt.show()

如何使用scatter_kws自定义pairplot中的标记样式

  1. <details>
  2. <summary>英文:</summary>
  3. I believe the mistake is one needs to use the plural &#39;markers&#39; instead of the singular &#39;marker&#39; in the scatter keywords dictionary. I would still be curious if anyone could improve on this answer.
  4. ```python
  5. import seaborn as sns
  6. import matplotlib.pyplot as plt
  7. # Load example dataset
  8. iris = sns.load_dataset(&quot;iris&quot;)
  9. # Define marker styles
  10. marker_styles = [&#39;o&#39;, &#39;s&#39;, &#39;D&#39;]
  11. # Map species to marker styles
  12. species_to_marker = {&#39;setosa&#39;: &#39;o&#39;, &#39;versicolor&#39;: &#39;s&#39;, &#39;virginica&#39;: &#39;D&#39;}
  13. # I believe the mistake was using &#39;marker&#39;: instead of &#39;markers&#39;:
  14. # Pass marker style column to scatterplot arguments
  15. scatter_kws = {&#39;s&#39;: 100, &#39;alpha&#39;: 0.5, &#39;style&#39;: iris[&#39;species&#39;], &#39;markers&#39;: species_to_marker}
  16. # Pass scatterplot arguments to pairplot
  17. sns.pairplot(iris, vars=[&quot;sepal_width&quot;, &quot;petal_length&quot;, &quot;petal_width&quot;],
  18. hue=&quot;species&quot;, diag_kind=&quot;kde&quot;, plot_kws=scatter_kws, corner=True)
  19. # Display the plot
  20. plt.show()

如何使用scatter_kws自定义pairplot中的标记样式

huangapple
  • 本文由 发表于 2023年5月18日 12:21:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76277707.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定