Seaborn 和 Matplotlib 子图中的独特图例

问题描述 投票:0回答:1

我正在分析一些数据并使用

matplotlib
seaborn
在两个子图上绘制三个小提琴图。

我的问题在于图例,我只想为图例之外的子图添加一个图例。

MWE 是:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.DataFrame({"A": np.random.uniform(size=100), "B": np.random.uniform(size=100), "Class": np.random.randint(0, 4, 100)})

fig, axs = plt.subplots(1, 2, sharey=True)

sns.violinplot(ax=axs[0], data=df[["A", "Class"]], x="Class", y="A")
axs[0].legend(["A"])

sns.violinplot(ax=axs[1], data=df[["B", "Class"]], x="Class", y="B", color="r")
axs[1].legend(["B"])

plt.show()

这个例子为每个子图放置一个图例,我希望它们都一起出现在图的右侧。

如果我尝试以这种方式提取标题和标签

lines_labels = [ax.get_legend_handles_labels() for ax in fig.axes]
,但这是一个空元组列表。

我尝试在图中添加

label
选项并绘制图例
plt.legend(loc="center left", bbox_to_anchor=(1.0, 0.5))
,但我获得了与我附加的相同图例重复 4 次的图相同的结果。

有什么建议吗?

python matplotlib seaborn
1个回答
0
投票

您可以简单地在

handles
中指定
labels
fig.legend()
:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.DataFrame({"A": np.random.uniform(size=100), "B": np.random.uniform(size=100), "Class": np.random.randint(0, 4, 100)})

fig, axs = plt.subplots(1, 2, sharey=True)

sns.violinplot(ax=axs[0], data=df[["A", "Class"]], x="Class", y="A")
sns.violinplot(ax=axs[1], data=df[["B", "Class"]], x="Class", y="B", color="r")

axs[0].set_ylabel("")

handle_a = axs[0].collections[0]
handle_b = axs[1].collections[0]

fig.legend(handles=[handle_a, handle_b], labels=["A", "B"], loc='center left', bbox_to_anchor=(1.0, 0.5))

plt.show()

© www.soinside.com 2019 - 2024. All rights reserved.