matplotlib 如何更改海运箱线图中线的颜色?

vnzz0bqm  于 2023-03-09  发布在  其他
关注(0)|答案(2)|浏览(291)

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

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吸烟者)改变颜色的选项,因为颜色可能不适用于两组。

von4xj4u

von4xj4u1#

可以自定义箱线图中的所有艺术家,如此处所示。由于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的作者正在考虑将来可能会添加这一点,例如,请看这里。

wwwo4jvm

wwwo4jvm2#

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

您可以使用medianprops来更改中值线的颜色。但是,所有箱线图只有一种颜色。如果您需要分配单独的颜色,您可以遍历生成的线。这使得代码对于不同的选项和未来可能的更改更加健壮。
ax1.get_lines()给出了由boxplot创建的所有Line2D对象的列表。对于组成一个框的每个元素,都有一个Line2D对象:4代表须线(2条垂直线和2条水平线),1代表中值,1代表离群值(Line2D显示无连接线的标记)。在showmeans=True的情况下,也会有Line2D显示平均值的标记。因此,在这种情况下,每个框将有7个Line2D,在本例中为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()

相关问题