在同一轴上绘制多个matplotlib箱线图并添加图例

28

我使用Matplotlib生成了一个箱线图:

enter image description here

然而,我不知道如何生成图例。每当我尝试以下操作时,都会出现错误,显示“Legend does not support {boxes: ...”。我已经进行过一些搜索,但似乎没有示例显示如何实现这一点。任何帮助将不胜感激!

bp1 = ax.boxplot(data1, positions=[1,4], notch=True, widths=0.35, patch_artist=True)
bp2 = ax.boxplot(data2, positions=[2,5], notch=True, widths=0.35, patch_artist=True)

ax.legend([bp1, bp2], ['A', 'B'], loc='upper right')
2个回答

43

boxplot返回一个艺术家字典。

结果: dict
将箱线图的每个组件映射到matplotlib.lines.Line2D实例列表的字典。该字典具有以下键(假设为垂直箱线图):

  • boxes: 箱线图的主体,显示四分位数和中位数的置信区间(如果启用)。
  • [...]

使用 boxes,您可以获取图例艺术家:

ax.legend([bp1["boxes"][0], bp2["boxes"][0]], ['A', 'B'], loc='upper right')

完整的示例:

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

data1=np.random.randn(40,2)
data2=np.random.randn(30,2)

fig, ax = plt.subplots()
bp1 = ax.boxplot(data1, positions=[1,4], notch=True, widths=0.35, 
                 patch_artist=True, boxprops=dict(facecolor="C0"))
bp2 = ax.boxplot(data2, positions=[2,5], notch=True, widths=0.35, 
                 patch_artist=True, boxprops=dict(facecolor="C2"))

ax.legend([bp1["boxes"][0], bp2["boxes"][0]], ['A', 'B'], loc='upper right')

ax.set_xlim(0,6)
plt.show()

输入图像描述


1
奇怪的是,这段代码对我不起作用。我想知道pyplot的某个版本是否出现了问题。图例出现了,但里面什么也没有。似乎legend()将其清除了。 - Chris A.
1
@ChrisA。抱歉,代码中当然有一个多余的 ax.legend。已经进行了更正。 - ImportanceOfBeingErnest
1
嗨@ImportanceOfBeingErnest,你知道我怎么改变“2”和“5”的标签吗?比如说把被呈现的变量名字放上去或者其他什么的。 - dekio
1
@dekio:这可以通过 ax.set_xticklabels(['A', 'B']) 来完成。 - Corbie

4

作为对@ImportanceOfBeingErnest回答的补充,如果你正在使用这样的for循环进行绘图:

for data in datas:
    ax.boxplot(data, positions=[1,4], notch=True, widths=0.35, 
             patch_artist=True, boxprops=dict(facecolor="C0"))

你不能将绘图保存为变量。因此,在这种情况下,需要创建一个图例标签列表legends,将绘图附加到另一个列表elements中,并使用列表推导式为每个绘图添加一个图例:

labels = ['A', 'B']
colors = ['blue', 'red']
elements = []

for dIdx, data in enumerate(datas):
    elements.append(ax.boxplot(data, positions=[1,4], notch=True,\
    widths=0.35, patch_artist=True, boxprops=dict(facecolor=colors[dIdx])))

ax.legend([element["boxes"][0] for element in elements], 
    [labels[idx] for idx,_ in enumerate(datas)])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接