sns.stripplot设置legend=False报错,求移除或调整图例方案
解决Seaborn Stripplot设置legend=False报错及图例位置问题
我使用Seaborn的stripplot和pointplot绘制数据,代码如下:
sns.set_palette("Purples") sns.stripplot( data=df_d_pt, x="feat", y="acc", hue="alpha", dodge=True, alpha=.2, legend=False, ) sns.pointplot( data=df_d_pt, x="feat", y="acc", hue="alpha", dodge=.4, linestyle="none", errorbar=None, marker="_", markersize=10, markeredgewidth=3, )
设置legend=False后触发报错,错误信息如下:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-156-18efd4be2baa> in <module> 3 sns.stripplot( 4 data=df_d_pt, x="feat", y="acc", hue="alpha", ----> 5 dodge=True, alpha=.2, legend=False, 6 ) 7 ~/.local/lib/python3.6/site-packages/seaborn/_decorators.py in inner_f(*args, **kwargs) 44 ) 45 kwargs.update({k: arg for k, arg in zip(sig.parameters, args)}) ---> 46 return f(**kwargs) 47 return inner_f 48 ~/.local/lib/python3.6/site-packages/seaborn/categorical.py in stripplot(x, y, hue, data, order, hue_order, jitter, dodge, orient, color, palette, size, edgecolor, linewidth, ax, **kwargs) 2820 linewidth=linewidth)) 2821 -> 2822 plotter.plot(ax, kwargs) 2823 return ax 2824 ~/.local/lib/python3.6/site-packages/seaborn/categorical.py in plot(self, ax, kws) 1158 def plot(self, ax, kws): 1159 """Make the plot.""" -> 1160 self.draw_stripplot(ax, kws) 1161 self.add_legend_data(ax) 1162 self.annotate_axes(ax) ~/.local/lib/python3.6/site-packages/seaborn/categorical.py in draw_stripplot(self, ax, kws) 1152 kws.update(c=palette[point_colors]) 1153 if self.orient == "v": -> 1154 ax.scatter(cat_pos, strip_data, **kws) 1155 else: 1156 ax.scatter(strip_data, cat_pos, **kws) /opt/conda/lib/python3.6/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs) 1445 def inner(ax, *args, data=None, **kwargs): 1446 if data is None: -> 1447 return func(ax, *map(sanitize_sequence, args), **kwargs) 1448 1449 bound = new_sig.bind(ax, *args, **kwargs) /opt/conda/lib/python3.6/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs) 409 else deprecation_addendum, 410 **kwargs) -> 411 return func(*inner_args, **inner_kwargs) 412 413 return wrapper /opt/conda/lib/python3.6/site-packages/matplotlib/axes/_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, plotnonfinite, **kwargs) 4496 ) 4497 collection.set_transform(mtransforms.IdentityTransform()) -> 4498 collection.update(kwargs) 4499 4500 if colors is None: /opt/conda/lib/python3.6/site-packages/matplotlib/artist.py in update(self, props) 994 func = getattr(self, f"set_{k}", None) 995 if not callable(func): -> 996 raise AttributeError(f"{type(self).__name__!r} object " 997 f"has no property {k!r}") 998 ret.append(func(v)) AttributeError: 'PathCollection' object has no property 'legend'
移除legend=False后,图例位置不符合需求(图例覆盖图表内容),需要实现移除图例或将图例移到图表右侧的效果。
报错原因
stripplot函数本身不支持legend参数,传入的legend=False会被当作额外参数传递给底层Matplotlib的scatter方法,而scatter返回的PathCollection对象没有legend属性,因此触发AttributeError。
解决方案
方案1:移除图例
去掉stripplot中的legend=False,绘图完成后通过Matplotlib API移除图例:
import matplotlib.pyplot as plt sns.set_palette("Purples") sns.stripplot( data=df_d_pt, x="feat", y="acc", hue="alpha", dodge=True, alpha=.2 ) sns.pointplot( data=df_d_pt, x="feat", y="acc", hue="alpha", dodge=.4, linestyle="none", errorbar=None, marker="_", markersize=10, markeredgewidth=3, ) # 方式1:清空图例内容 plt.legend([], [], frameon=False) # 方式2:直接移除图例对象(更简洁) # plt.gca().get_legend().remove()
方案2:将图例移到图表右侧
同样去掉stripplot中的legend=False,通过Matplotlib调整图例位置,避免覆盖图表:
import matplotlib.pyplot as plt sns.set_palette("Purples") sns.stripplot( data=df_d_pt, x="feat", y="acc", hue="alpha", dodge=True, alpha=.2 ) sns.pointplot( data=df_d_pt, x="feat", y="acc", hue="alpha", dodge=.4, linestyle="none", errorbar=None, marker="_", markersize=10, markeredgewidth=3, ) # 将图例移到图表右侧,bbox_to_anchor参数避免覆盖图表 plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0) # 调整布局防止图例被裁剪 plt.tight_layout()
内容的提问来源于stack exchange,提问作者Kadaj13
相关产品推荐
相关产品推荐

