如何用 4 个图例而不是 2 个图例更改 python pyplot 图例

How to change python pyplot legend with 4 legend instead of 2

感谢您花时间回答我的问题。

我有 2 个由几列组成的 DataFrame:

df=pd.DataFrame([['A',10, 22], ['A',12, 15], ['A',0, 2], ['A', 20, 25], ['A', 5, 5], ['A',12, 11], ['B', 0 ,0], ['B', 9 ,0], ['B', 8 ,50], ['B', 0 ,0], ['B', 18 ,5], ['B', 7 ,6],['C', 10 ,11], ['C', 9 ,10], ['C', 8 ,2], ['C', 6 ,2], ['C', 8 ,5], ['C', 6 ,8]],
         columns=['Name', 'Value_01','Value_02'])
df_agreement=pd.DataFrame([['A', '<66%', '>80'],['B', '>80%', '>66% & <80%'], ['C', '<66%', '<66%']], columns=['Name', 'Agreement_01', 'Agreement_02'])

我的目标是为此 DataFrame 创建箱线图,其中 ['Value_01'、'Value_02'] 作为值,'Name' 作为 x 值。为此,我使用以下代码执行 sns 箱线图:

fig = plt.figure()
# Change seaborn plot size
fig.set_size_inches(60, 40)
plt.xticks(rotation=70)
plt.yticks(fontsize=40)
df_02=pd.melt(df, id_vars=['Name'],value_vars=['Value_01', 'Value_02'])
bp=sns.boxplot(x='Name',y='value',hue="variable",showfliers=True, data=df_02,showmeans=True,meanprops={"marker": "+", 
                       "markeredgecolor": "black", 
                       "markersize": "20"})
bp.set_xlabel("Name", fontsize=45)
bp.set_ylabel('Value', fontsize=45)
bp.legend(handles=bp.legend_.legendHandles, labels=['V_01', 'V_02'])

好的,这部分有效,我有 6 个箱线图,每个名字两个。

变得棘手的是,我想使用 df_agreement 来更改我的箱线图的颜色,无论是否 <66%。所以我在我的代码中添加了这个:

list_color_1=[]
list_color_2=[]
for i in range(0, len(df_agreement)):
    name=df_agreement.loc[i,'Name']
    if df_agreement.loc[i,'Agreement_01']=="<66%":
        list_color_1.append(i*2)
    if df_agreement.loc[i,'Agreement_02']=="<66%":
        list_color_2.append(i*2+1)
for k in list_color_1:
    mybox = bp.artists[k]
    # Change the appearance of that box
    mybox.set_facecolor("#D1DBE6") #facecolor is the inside color of the boxplot
    mybox.set_edgecolor('black') #edgecolor is the line color of the box
    mybox.set_linewidth(2)
for k in list_color_2:
    mybox = bp.artists[k]
    # Change the appearance of that box
    mybox.set_facecolor("#EFDBD1") #facecolor is the inside color of the boxplot
    mybox.set_edgecolor('black') #edgecolor is the line color of the box
    mybox.set_linewidth(2)

效果很好,我的箱线图已根据 df_agreement 上的值进行了更改。 但是,不幸的是,我还想用 ["V_01"、"V_02"、"V_01 with less 66% agreement"、"V_02 with less 66% agreement"],明显与图例中对应的颜色。

您有执行此操作的想法吗?

非常感谢! :)

您可以添加自定义图例元素,扩展句柄列表。这是一个例子。

handles, labels = bp.get_legend_handles_labels()
new_handles = handles + [plt.Rectangle((0, 0), 0, 0, facecolor="#D1DBE6", edgecolor='black', linewidth=2),
                         plt.Rectangle((0, 0), 0, 0, facecolor="#EFDBD1", edgecolor='black', linewidth=2)]
bp.legend(handles=new_handles,
          labels=['V_01', 'V_02', "V_01 with less\n than 66% agreement", "V_02 with less\n than 66% agreement"])