【问题标题】:How to add a single legend label for a set of boxplots?如何为一组箱线图添加单个图例标签?
【发布时间】:2018-01-30 10:36:54
【问题描述】:

有没有更好的方法将单个标签添加到箱线图集的图例中?

下面是一个简单的示例,它给出了预期的结果。这是通过创建一条带有所需标签的不可见线 (alpha=0) 完成的,然后通过 legendHandles 更改 alpha。但是,是否可以将所有箱线图的单个标签传递给sns.boxplot()

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

# Get the tips dataset and select a subset as an example
tips = sns.load_dataset("tips")
variable_to_bin_by = 'tip'
binned_variable = 'total_bill'
df = tips[ [binned_variable,  variable_to_bin_by] ]  

# Group the data by a list of bins
bins = np.array([0, 1, 2, 3, 4])
gdf = df.groupby( pd.cut(df[variable_to_bin_by].values, bins ) )
data = [ i[1][binned_variable].values for i in gdf]
df = pd.DataFrame( data, index = bins[:-1])   

# Plot the data (using boxplots to show spread of real values)
fig, ax = plt.subplots()
ax = sns.boxplot( data=df.T, ax=ax, color='k')

# Create hidden line with the extra label (to give label to boxplots)
x = np.range(10)
plt.plot(x, x, label='REAL DATA', color='k', alpha=0)

# Now plot some "model fit" lines
models = {'model1': bins+10, 'model2': bins+10*1.5, 'model3': bins*10}
for key in sorted( models.keys() ):
    plt.plot( bins, models[key], label=key )

# Add a legend
leg = plt.legend()

# Update line visibility (alpha)
for legobj in leg.legendHandles:
        legobj.set_alpha( 1 )

# Show the plot
plt.show()

虽然这给出了预期的结果(如下所示),但我的问题是是否有更好的方法?

【问题讨论】:

    标签: python matplotlib plot seaborn boxplot


    【解决方案1】:

    您可以直接创建一个空行,其中包含要在图例中显示的属性(此处,颜色)。

    plt.plot([], [], label='REAL DATA', color='k')
    

    这避免了在情节和图例中使用 alpha。 完整的示例如下所示:

    import seaborn as sns
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Get the tips dataset and select a subset as an example
    tips = sns.load_dataset("tips")
    variable_to_bin_by = 'tip'
    binned_variable = 'total_bill'
    df = tips[ [binned_variable,  variable_to_bin_by] ]  
    
    # Group the data by a list of bins
    bins = np.array([0, 1, 2, 3, 4])
    gdf = df.groupby( pd.cut(df[variable_to_bin_by].values, bins ) )
    data = [ i[1][binned_variable].values for i in gdf]
    df = pd.DataFrame( data, index = bins[:-1])   
    
    # Plot the data (using boxplots to show spread of real values)
    fig, ax = plt.subplots()
    ax = sns.boxplot( data=df.T, ax=ax, color="grey")
    
    # Create hidden line with the extra label (to give label to boxplots)
    plt.plot([], [], label='REAL DATA', color='k')
    
    # Now plot some "model fit" lines
    models = {'model1': bins+10, 'model2': bins+10*1.5, 'model3': bins*10}
    for key in sorted( models.keys() ):
        plt.plot( bins, models[key], label=key, zorder=3)
    
    # Add a legend
    leg = plt.legend()
    
    # Show the plot
    plt.show()
    

    【讨论】:

    • 感谢您的意见。我想我真的想问是否有办法将标签传递给sns.boxplot() 并让plt.legend() 找到它。我检查了一下,我确实已经在我的代码的其他地方使用了你建议的空行创建 (and as shown by this answer),但当我快速将问题放在一起时,我只是忘了使用它。
    • 即使是 matplotlib boxplot 函数也没有指定图例标签的选项。因为 seaborn 本质上只是调用 matplotlib boxplot 函数,所以它也不提供该选项。从这个意义上说,答案很简单:不!
    猜你喜欢
    • 2021-12-06
    • 1970-01-01
    • 2022-11-24
    • 2018-04-08
    • 2019-01-22
    • 2021-02-03
    • 2018-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多