使用Seaborn在单图中绘制双图并合并图例的问题
合并双轴图表的图例(直方图+折线图)
我尝试在一张图中绘制两种图表:基于state和group统计频率的直方图,以及基于state统计target数值的折线图。希望将两个坐标轴(ax、ax2)的图例合并到同一个图例框中,但两种尝试方法均存在问题:
- 方法1:可运行但生成两个独立图例框
h2, l2 = ax2.get_legend_handles_labels() ax2.legend(h2, l2)
- 方法2:仅显示
target标签
h1, l1 = ax.get_legend_handles_labels() h2, l2 = ax2.get_legend_handles_labels() ax.legend(h1+h2, l1+l2, loc=2)
完整代码如下:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt data = { 'state': ['nj', 'nj', 'nj', 'ny', 'ny', 'ny'], 'group': ['A', 'A', 'B', 'A', 'B', 'B'], 'target': [20, 21, 19, 18, 15, 33] } df_test1 = pd.DataFrame(data) fig, ax = plt.subplots(figsize=(10, 6)) sns.histplot( data=df_test1, x='state', hue='group', hue_order=['A', 'B'], multiple='dodge', ax=ax, shrink=.5, ) ax2 = ax.twinx() sns.lineplot( data=df_test1, x='state', y='target', label='target', ax=ax2, ) h1, l1 = ax.get_legend_handles_labels() h2, l2 = ax2.get_legend_handles_labels() ax.legend(h1+h2, l1+l2, loc=2)
问题原因
方法2失效是因为seaborn.histplot使用hue参数时,默认不会将图例句柄直接存储在ax对象中,而是由Seaborn内部管理,导致ax.get_legend_handles_labels()返回空值。
解决代码
通过先让Seaborn生成直方图的图例,提取其句柄和标签后删除原始图例,再与折线图的图例元素合并:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt data = { 'state': ['nj', 'nj', 'nj', 'ny', 'ny', 'ny'], 'group': ['A', 'A', 'B', 'A', 'B', 'B'], 'target': [20, 21, 19, 18, 15, 33] } df_test1 = pd.DataFrame(data) fig, ax = plt.subplots(figsize=(10, 6)) # 绘制直方图并获取图例元素 hist_plot = sns.histplot( data=df_test1, x='state', hue='group', hue_order=['A', 'B'], multiple='dodge', ax=ax, shrink=.5, ) h1, l1 = hist_plot.get_legend_handles_labels() ax.get_legend().remove() # 删除直方图的原始图例 # 绘制折线图并获取图例元素 ax2 = ax.twinx() line_plot = sns.lineplot( data=df_test1, x='state', y='target', label='target', ax=ax2, ) h2, l2 = line_plot.get_legend_handles_labels() ax2.get_legend().remove() # 删除折线图的原始图例 # 合并所有图例元素到同一个图例框 ax.legend(h1 + h2, l1 + l2, loc=2) plt.show()
效果说明
运行修改后的代码后,会生成一个包含直方图的A、B分类和折线图的target指标的统一图例框,解决了双轴图例分散或缺失的问题。
内容的提问来源于stack exchange,提问作者shsh
相关产品推荐
相关产品推荐

