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

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

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:

import seaborn as sns
import matplotlib.pyplot as plt

iris = sns.load_dataset("iris")
marker_styles = ['o', 's', 'D']

species_to_marker = {'setosa': 'o', 'versicolor': 's', 'virginica': 'D'}
iris['markers'] = iris['species'].map(species_to_marker)

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

sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
             hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)

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.

import seaborn as sns
import matplotlib.pyplot as plt

# Load example dataset
iris = sns.load_dataset("iris")

# Define marker styles "Circle", "Square", "Diamond"
marker_styles = ['o', 's', 'D']  


# Map species to marker styles  (read again as  "Circle", "Square", "Diamond")
species_to_marker = {'setosa': 'o', 'versicolor': 's', 'virginica': 'D'}
iris['markers'] = iris['species'].map(species_to_marker)

# Pass marker style column to scatterplot arguments
# This sort of works:  at least maps the variable to the default marker style:
scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species']}  # 'style' assigns DEFAULT markers which can be interpreted as "circle, x, square"  

# This doesn't work: I want to use my non-default markers that are mapped to the variable:
# 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']


# Pass scatterplot arguments to pairplot, only plot lower-left-triangle of pairs
sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
             hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)

# Display the plot
plt.show()

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

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

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

TypeError                                 Traceback (most recent call last)
<ipython-input-600-3640788f836b> in <cell line: 21>()
     19 
     20 # Pass scatterplot arguments to pairplot
---> 21 sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
     22              hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)
     23 

8 frames
/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)
   2156     if kind == "scatter":
   2157         from .relational import scatterplot  # Avoid circular import
-> 2158         plotter(scatterplot, **plot_kws)
   2159     elif kind == "reg":
   2160         from .regression import regplot  # Avoid circular import

/usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in map_offdiag(self, func, **kwargs)
   1417         """
   1418         if self.square_grid:
-> 1419             self.map_lower(func, **kwargs)
   1420             if not self._corner:
   1421                 self.map_upper(func, **kwargs)

/usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in map_lower(self, func, **kwargs)
   1387         """
   1388         indices = zip(*np.tril_indices_from(self.axes, -1))
-> 1389         self._map_bivariate(func, indices, **kwargs)
   1390         return self
   1391 

/usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in _map_bivariate(self, func, indices, **kwargs)
   1566             if ax is None:  # i.e. we are in corner mode
   1567                 continue
-> 1568             self._plot_bivariate(x_var, y_var, ax, func, **kws)
   1569         self._add_axis_labels()
   1570 

/usr/local/lib/python3.10/dist-packages/seaborn/axisgrid.py in _plot_bivariate(self, x_var, y_var, ax, func, **kwargs)
   1607                 "hue": hue, "hue_order": self._hue_order, "palette": self._orig_palette,
   1608             })
-> 1609         func(x=x, y=y, **kwargs)
   1610 
   1611         self._update_legend_data(ax)

/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)
    759     kwargs["color"] = _default_color(ax.scatter, hue, color, kwargs)
    760 
--> 761     p.plot(ax, kwargs)
    762 
    763     return ax

/usr/local/lib/python3.10/dist-packages/seaborn/relational.py in plot(self, ax, kws)
    566         if not isinstance(m, mpl.markers.MarkerStyle):
    567             # TODO in more recent matplotlib (which?) can pass a MarkerStyle here
--> 568             m = mpl.markers.MarkerStyle(m)
    569         if m.is_filled():
    570             kws.setdefault("edgecolor", "w")

/usr/local/lib/python3.10/dist-packages/matplotlib/markers.py in __init__(self, marker, fillstyle, transform, capstyle, joinstyle)
    270                 "%(since)s; support will be removed %(removal)s.  Use "
    271                 "MarkerStyle('') to construct an empty MarkerStyle.")
--> 272         self._set_marker(marker)
    273 
    274     __init__.__signature__ = inspect.signature(  # Only for deprecation period.

/usr/local/lib/python3.10/dist-packages/matplotlib/markers.py in _set_marker(self, marker)
    349             self._marker_function = self._set_tuple_marker
    350         elif (not isinstance(marker, (np.ndarray, list)) and
--> 351               marker in self.markers):
    352             self._marker_function = getattr(
    353                 self, '_set_' + self.markers[marker])

TypeError: unhashable type: 'Series'

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

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

but this raises the following ValueError:

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 关键词字典中。我仍然很好奇是否有人能改进这个答案。

import seaborn as sns
import matplotlib.pyplot as plt

# 加载示例数据集
iris = sns.load_dataset("iris")

# 定义标记样式
marker_styles = ['o', 's', 'D']

# 将物种映射到标记样式
species_to_marker = {'setosa': 'o', 'versicolor': 's', 'virginica': 'D'}

# 我相信错误在于使用 'marker': 而不是 'markers':
# 将标记样式列传递给散点图参数
scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species'], 'markers': species_to_marker}

# 将散点图参数传递给 pairplot
sns.pairplot(iris, vars=["sepal_width", "petal_length", "petal_width"],
             hue="species", diag_kind="kde", plot_kws=scatter_kws, corner=True)

# 显示图表
plt.show()

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


<details>
<summary>英文:</summary>

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.

```python 
import seaborn as sns
import matplotlib.pyplot as plt

# Load example dataset
iris = sns.load_dataset(&quot;iris&quot;)

# Define marker styles
marker_styles = [&#39;o&#39;, &#39;s&#39;, &#39;D&#39;]


# Map species to marker styles
species_to_marker = {&#39;setosa&#39;: &#39;o&#39;, &#39;versicolor&#39;: &#39;s&#39;, &#39;virginica&#39;: &#39;D&#39;}
 
# I believe the mistake was using &#39;marker&#39;: instead of &#39;markers&#39;:
# Pass marker style column to scatterplot arguments
scatter_kws = {&#39;s&#39;: 100, &#39;alpha&#39;: 0.5, &#39;style&#39;: iris[&#39;species&#39;],  &#39;markers&#39;: species_to_marker}


# Pass scatterplot arguments to pairplot
sns.pairplot(iris, vars=[&quot;sepal_width&quot;, &quot;petal_length&quot;, &quot;petal_width&quot;],
             hue=&quot;species&quot;, diag_kind=&quot;kde&quot;, plot_kws=scatter_kws, corner=True)

# Display the plot
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:

确定