如何为Seaborn histplot的柱状图添加填充图案及图例
解决Seaborn堆叠直方图(histplot)添加填充图案图例的问题
问题原因
在multiple='stack'模式下的histplot,其生成的每个堆叠区块(patch)的标签以下划线开头(如_0、_1),Matplotlib默认会忽略这类标签的元素,直接调用plt.legend()会找不到有效图例项;同时Seaborn自动生成的默认图例并未同步应用你设置的填充图案(hatch),导致无法显示带填充的图例。
解决方案
通过获取Seaborn自动生成的图例元素,为其同步设置填充图案后重新生成图例即可,完整代码如下:
import matplotlib.pyplot as plt import seaborn as sns tips = sns.load_dataset("tips") hatches = ['\\\\', '//'] fig, ax = plt.subplots(figsize=(6,3)) # 执行histplot,生成堆叠直方图 sns.histplot(data=tips, x="total_bill", hue="time", multiple='stack') # 为每个堆叠层的区块设置填充图案 for container, hatch in zip(ax.containers, hatches): for patch in container: patch.set_hatch(hatch) # 获取原始图例的手柄(handles)和标签(labels) handles, labels = ax.get_legend_handles_labels() # 为图例手柄同步设置对应的填充图案 for handle, hatch in zip(handles, hatches): handle.set_hatch(hatch) # 重新生成带填充图案的图例 ax.legend(handles=handles, labels=labels, loc='best') plt.show()
代码说明
- 设置填充图案:遍历
ax.containers(每个容器对应一个hue分组),为组内所有区块设置对应的填充样式。 - 同步图例样式:通过
ax.get_legend_handles_labels()获取Seaborn自动生成的图例元素,为每个手柄(handle)设置和对应区块一致的填充图案。 - 更新图例:调用
ax.legend()传入更新后的手柄和标签,生成带填充图案的图例。
备选方案(手动创建图例)
如果需要更灵活控制图例元素,可手动创建图例补丁(Patch):
import matplotlib.pyplot as plt import seaborn as sns import matplotlib.patches as mpatches tips = sns.load_dataset("tips") hatches = ['\\\\', '//'] fig, ax = plt.subplots(figsize=(6,3)) sns.histplot(data=tips, x="total_bill", hue="time", multiple='stack') # 设置填充图案 for container, hatch in zip(ax.containers, hatches): for patch in container: patch.set_hatch(hatch) # 手动创建图例补丁,指定颜色、填充图案和标签 legend_patches = [ mpatches.Patch( facecolor=ax.containers[i].patches[0].get_facecolor(), hatch=hatches[i], label=label ) for i, label in enumerate(['Lunch', 'Dinner']) ] ax.legend(handles=legend_patches, loc='best') plt.show()
内容的提问来源于stack exchange,提问作者Ernesto
相关产品推荐
相关产品推荐

