matplotlib 如何改变箱线图中线的颜色

pdsfdshx  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(217)

更一般地说,如何更改海运箱线图中框属性子集的颜色值?可以是中位数,胡须等。我对如何更改中位数值特别感兴趣,因为我必须创建具有深色的图,并且中线不能被看到。
下面是一些示例代码:

import matplotlib.pyplot as plt
import seaborn as sns

fig, ax1 = plt.subplots(figsize=(15,5)

colours = ["#000184", "#834177"]
sns.set_palette(sns.color_palette(colours))
tips = sns.load_dataset("tips")
sns.boxplot(x="day", y="total_bill", hue="smoker", data=tips, ax=ax1)

这就产生了:

可以看到,很难看到中间线与蓝色的对比。
注意-我不想改变整个箱形图的颜色,只是一部分线(在这种情况下是中位数)。此外-需要为特定组(在这种情况下是Yes吸烟者)更改它的选项,因为颜色可能不适用于两个组。

uyto3xhc

uyto3xhc1#

可以自定义箱线图中的所有艺术家,如此处所示。由于sns.boxplot()将所有**kwargs转发到plt.boxplot(),因此可以执行以下操作:

tips = sns.load_dataset("tips")
colours = ["#000184", "#834177"]
sns.boxplot(x="day", y="total_bill", hue="smoker",
            data=tips, palette=colours,
            medianprops=dict(color="red", alpha=0.7),
            flierprops=dict(markerfacecolor="#707070", marker="d"))

通过这种方式,可以修改框的美观性,“飞行器”(代表异常值的点),中位数或平均线,以及须线/帽线。请参阅plt.boxplot()的文档以获得可修改属性的完整列表。
不幸的是,上面的方法不能像OP所期望的那样调整每个类别的属性。但是使用透明颜色(例如alpha=0.4)仍然可以得到非常令人满意的结果。
注意:如果seaborn以结构化的方式公开艺术家的信息,这将是非常好的。虽然这在当前版本(seaborn v0.11)中是不可能的,seaborn的作者正在考虑将来可能会添加这一点,例如,请参阅这里。

rsaldnfx

rsaldnfx2#

**更新:**旧版本的答案使用生成的线中的索引来猜测图中哪条线对应于中线。新版本为每个均值添加了一个特殊的标签,稍后可以检索该标签以仅过滤掉这些线。

您可以使用medianprops来更改中间线的颜色。但是,所有箱线图只有一种颜色。如果您需要分配单个颜色,您可以循环生成的线。这使得代码对不同的选项和未来可能的更改更加健壮。
ax1.get_lines()给出了由boxplot创建的所有Line2D对象的列表。对于组成盒子的每个元素,都会有一个Line2D对象:4表示须线(2条垂直线和2条水平线),1表示中位数,1表示离群值(它是一个Line2D,显示没有连接线的标记)。在showmeans=True的情况下,也会有一个Line2D,其中有一个标记表示均值。因此在这种情况下,每个框将有7个Line2D s,在这种情况下为6。
请注意,箱形图也接受一个参数notch=True,该参数显示中位数周围的置信区间。在当前图中,大多数置信区间都大于四分位数,这会产生一些翻转的凹口。根据真实的应用,这些凹口有助于突出中位数。

import matplotlib.pyplot as plt
import seaborn as sns

fig, ax1 = plt.subplots(figsize=(15,5))

colours = ["#000184", "#834177"]
sns.set_palette(sns.color_palette(colours))
tips = sns.load_dataset("tips")

sns.boxplot(x="day", y="total_bill", hue="smoker", data=tips, ax=ax1,
            medianprops={'color': 'red', 'label': '_median_'})

median_colors = ['orange', 'yellow']
median_lines = [line for line in ax1.get_lines() if line.get_label() == '_median_']
for i, line in enumerate(median_lines):
    line.set_color(median_colors[i % len(median_colors)])
plt.show()

相关问题