matplotlib 根据 hue colormap 组改变 boxplot mean/median

matplotlib change boxplot mean/median according to hue colormap group

我在为 matplotlib 和 seaborn 分别设置色相组的均值或中值颜色时遇到了一些问题。

为了测试,我在这里生成了一些基本数据

import seaborn as sn 
import pandas as pd
import numpy as np 

arr_num = np.random.randint(0, 4, (3, 1000))
df = pd.DataFrame(arr_num.T)
df["cat"] = np.random.choice(a=['a', 'b'],  size=1000)
df.columns = ["num_1", "num_2", "num_3", "cat_1"]
df.head()

然后调用seaborn boxplot函数:

ax = sn.boxplot(data=df, x="num_1", y="num_2", hue="cat_1", palette="viridis", \
          medianprops={"color":"blue"})

这里的medianpropos参数实际上是一个matplotlib.lines.Line2D,只允许color参数。在上面的示例中,我将其设置为蓝色,但我没有看到为两个“色调”组指定不同颜色的选项。

理论上我可以用 seaborn.color_palette 函数生成两种颜色,例如sn.color_palette("viridis", 2)。但我仍然没有看到任何方法来为各个组指定这些。

在此先感谢您的帮助!

感谢@JohanC的讨论,似乎没有简单的方法。 所以我在这里发布了我的“hacky”解决方案,该解决方案将中值道具固定为某个 alpha 值,然后遍历它来设置颜色图的特定值。为了更好的代码可见性,我将框设置为较低的 alpha 值。

ax = sn.boxplot(data=df, x="num_1", y="num_2", hue="cat_1", palette="viridis", \
          medianprops={"alpha":0.0124})

hue_colors = sn.color_palette("viridis", df["cat_1"].unique().shape[0])

for patch in ax.artists:
    r, g, b, a = patch.get_facecolor()
    patch.set_facecolor((r, g, b, .1))

switch_ = 0
for line in ax.lines:
    if line.get_alpha() == 0.0124:
        
        line.set_color(hue_colors[switch_])
        switch_ += 1
        
        if switch_ >= len(hue_colors):
            switch_ = 0
            
        line.set_alpha(1)

编辑:要更改平均颜色而不是中位数,set_color 函数将不起作用。而是独立设置边色和面色:

line._markerfacecolor = hue_colors[switch_]
line._markeredgecolor = hue_colors[switch_]