将 seaborn 传说与 histplot 相结合

Combine seaborn legends with histplot

下面有四个独立的子图。这个数字是预期的,传说很好。但我为每个子图添加了单独的一行,并希望将其包含在图例中。但是,我似乎无法包含它。我尝试了一些方法,但似乎没有任何效果。

选项 1 不包括该行,而选项 2 包括但顺序向后且不准确。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(0,4,size=(100, 4)), columns=list('ABCD'))
df['String'] = np.random.choice(['yes','no','maybe'],len(df))
df['String'] = pd.Categorical(df['String'], ['yes','no','maybe'])


def fig(df):

    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2,2, figsize = (8,10))

    ax1 = sns.histplot(data = df, 
             x = 'A', 
             hue = 'String',
             multiple = 'fill', 
             ax = ax1
             )

    ax2 = sns.histplot(data = df, 
             x = 'B', 
             hue = 'String',
             multiple = 'fill', 
             ax = ax2
             )

    ax3 = sns.histplot(data = df, 
             x = 'C', 
             hue = 'String',
             multiple = 'fill', 
             ax = ax3
             )

    ax4 = sns.histplot(data = df, 
             x = 'D', 
             hue = 'String',
             multiple = 'fill', 
             ax = ax4
             )

    ax1.axhline(0.2, color = 'b', linestyle = '--', label = 'avg')
    ax2.axhline(0.5, color = 'b', linestyle = '--', label = 'avg')
    ax3.axhline(0.8, color = 'b', linestyle = '--', label = 'avg')
    ax4.axhline(0.9, color = 'b', linestyle = '--', label = 'avg')

    # option 1
    #legend = ax1.get_legend()
    #handles = legend.legendHandles
    #legend.remove()
    #ax1.legend(handles, ['yes','no','maybe', 'avg'])

    # option 2
    h,labels = ax1.get_legend_handles_labels()
    h = ['yes','no','maybe', 'avg']

    ax1.legend(h,loc=2)

fig(df)

你可以使用选项1中的方法在不擦除图例的情况下获取水平线的图例,然后将它们中的每一个组合起来。代码只调整了第一个图例,其他图例大家可以照着这个例子修改。

# option 1
legend = ax1.get_legend()
print(legend.get_texts())
handles = legend.legendHandles
print(handles)
h,l = ax1.get_legend_handles_labels()
print(l)
print(h)
l = ['yes','no','maybe','avg']
ax1.legend(handles+h, l, title='String')