【问题标题】:Background with range on seaborn based on two columns基于两列的 seaborn 范围背景
【发布时间】:2021-05-15 14:07:55
【问题描述】:

我正在尝试在我的几个线图中添加一个背景,该背景显示每年从值 x(列“Min”)到值 y(列“Max”)的范围。我的数据集如下所示:

        Country Model   Year    Costs   Min Max
    494 FR  1   1990    300     250     350
    495 FR  1   1995    250     300     400
    496 FR  1   2000    220     330     640
    497 FR  1   2005    210     289     570
    498 FR  2   1990    400     250     350
    555 JPN 8   1990    280     250     350
    556 JPN 8   1995    240     300     400
    557 JPN 8   2000    200     330     640
    558 JPN 8   2005    200     289     570

我使用了以下代码:

example_1 = sns.relplot(data=example, x = "Year", y = "Costs", hue = "Model", style = "Model", col = "Country", kind="line", col_wrap=4,height = 4, dashes = True, markers = True, palette = palette, style_order = style_order)

我想要这样的东西,范围是我每年的“最小”和“最大”。

有可能吗? 非常感谢!

【问题讨论】:

  • 我的回答是否提供了您正在寻找的解决方案?
  • 你好帕特里克!您的回答正是我正在寻找的解决方案!非常感谢您的详细解释!

标签: python pandas matplotlib seaborn


【解决方案1】:

通常,grid.map 是执行此操作的工具,如mutli-plot grids tutorial 中的许多示例所示。但是您正在使用 relplotlineplotFacetGrid 组合在一起,因为建议使用 in the docs(最后一个示例),这可以让您使用一些额外的样式参数。

因为relplot 处理数据的方式与您首先启动FacetGrid 然后映射lineplot(您可以使用grid.data 进行检查)略有不同,因此使用grid.map(plt.bar, ...) 绘制范围是相当麻烦,因为它需要编辑 grid.data 数据框以及 x 轴和 y 轴标签。

绘制范围最简单的方法是循环遍历grid.axes。这可以通过grid.axes_dict.items() 来完成,它提供了列名称(即国家/地区),您可以使用这些名称为条形选择适当的数据(如果范围不同,则很有用,与本示例相反)。

默认图形图例不包含完整的图例,包括范围的键,但第一个 ax 对象会显示一个而不是以下示例中的默认图例。请注意,我已经编辑了您共享的数据,以便最小/最大范围更有意义:

import io
import pandas as pd              # v 1.1.3
import matplotlib.pyplot as plt  # v 3.3.2
import seaborn as sns            # v 0.11.0

data ='''
 Country Model   Year    Costs   Min Max
    494 FR  1   1990    300     250     350
    495 FR  1   1995    250     200     300
    496 FR  1   2000    220     150     240
    497 FR  1   2005    210     189     270
    555 JPN 8   1990    280     250     350
    556 JPN 8   1995    240     200     300
    557 JPN 8   2000    200     150     240
    558 JPN 8   2005    200     189     270
'''
df = pd.read_csv(io.StringIO(data), delim_whitespace=True)

# Create seaborn FacetGrid with line plots
grid = sns.relplot(data=df, x='Year', y='Costs', hue='Model', style='Model',height=3.9,
                   col='Country', kind='line', markers=True, palette='tab10')

# Loop through axes of the FacetGrid to plot bars for ranges and edit x ticks
for country, ax in grid.axes_dict.items():
    df_country = df[df['Country'] == country]
    cost_range = df_country['Max']-df_country['Min']
    ax.bar(x=df_country['Year'], height=cost_range, bottom=df_country['Min'], 
           color='black', alpha=0.1, label='Min/max\nrange')
    ax.set_xticks(df_country['Year'])

# Remove default seaborn figure legend and show instead full legend stored in first ax
grid._legend.remove()
grid.axes.flat[0].legend(bbox_to_anchor=(2.1, 0.5), loc='center left',
                         frameon=False, title=grid.legend.get_title().get_text());

【讨论】:

    猜你喜欢
    • 2020-04-10
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多