英文:
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()
<details>
<summary>英文:</summary>
I believe the mistake is one needs to use the plural 'markers' instead of the singular 'marker' 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("iris")
# Define marker styles
marker_styles = ['o', 's', 'D']
# Map species to marker styles
species_to_marker = {'setosa': 'o', 'versicolor': 's', 'virginica': 'D'}
# I believe the mistake was using 'marker': instead of 'markers':
# Pass marker style column to scatterplot arguments
scatter_kws = {'s': 100, 'alpha': 0.5, 'style': iris['species'], 'markers': species_to_marker}
# Pass scatterplot arguments to pairplot
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()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论