首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Seaborn boxplot

Seaborn boxplot
EN

Stack Overflow用户
提问于 2021-10-21 17:50:22
回答 1查看 140关注 0票数 0

我有一个多索引的Pandas数据帧,我想要将其绘制为箱线图。这应该很容易做到,但我发现自己无法得到我想要的东西。数据如下所示:

代码语言:javascript
复制
                       hedges  mask model_name  hedges_std  hedges_min  \
    period    season                                                      
    2021-2025 winter  0.864328   1.0   ensemble    0.301748    0.124708   
          spring  0.740410   1.0   ensemble    0.202963    0.049319   
          summer  0.526264   1.0   ensemble    0.105750    0.162856   
          fall    0.531141   1.0   ensemble    0.046278    0.388827   
2025-2050 winter  1.715075   1.0   ensemble    0.373866    0.582819   
          spring  1.252963   1.0   ensemble    0.370402    0.408695   
          summer  0.854958   1.0   ensemble    0.076193    0.528038   
          fall    0.759645   1.0   ensemble    0.068928    0.498271   
2050-2075 winter  2.981373   1.0   ensemble    0.928940    1.139801   
          spring  2.042320   1.0   ensemble    0.748642    0.716289   
          summer  1.299277   1.0   ensemble    0.092611    0.812979   
          fall    1.108852   1.0   ensemble    0.109014    0.653199   
2021-2025 winter  0.864328   1.0   ensemble    0.301748    0.124708   
          spring  0.740410   1.0   ensemble    0.202963    0.049319   
          summer  0.526264   1.0   ensemble    0.105750    0.162856   
          fall    0.531141   1.0   ensemble    0.046278    0.388827   
2025-2050 winter  1.715075   1.0   ensemble    0.373866    0.582819   
          spring  1.252963   1.0   ensemble    0.370402    0.408695   
          summer  0.854958   1.0   ensemble    0.076193    0.528038   
          fall    0.759645   1.0   ensemble    0.068928    0.498271   
2050-2075 winter  2.981373   1.0   ensemble    0.928940    1.139801   
          spring  2.042320   1.0   ensemble    0.748642    0.716289   
          summer  1.299277   1.0   ensemble    0.092611    0.812979   
          fall    1.108852   1.0   ensemble    0.109014    0.653199   

                  hedges_max model_scenario  
period    season                             
2021-2025 winter    1.760912         ssp245  
          spring    1.189956         ssp245  
          summer    0.662142         ssp245  
          fall      0.687793         ssp245  
2025-2050 winter    2.423660         ssp245  
          spring    2.040903         ssp245  
          summer    1.055890         ssp245  
          fall      0.965831         ssp245  
2050-2075 winter    5.179203         ssp245  
          spring    3.898118         ssp245  
          summer    1.536149         ssp245  
          fall      1.435503         ssp245  
2021-2025 winter    1.760912         ssp585  
          spring    1.189956         ssp585  
          summer    0.662142         ssp585  
          fall      0.687793         ssp585  
2025-2050 winter    2.423660         ssp585  
          spring    2.040903         ssp585  
          summer    1.055890         ssp585  
          fall      0.965831         ssp585  
2050-2075 winter    5.179203         ssp585  
          spring    3.898118         ssp585  
          summer    1.536149         ssp585  
          fall      1.435503         ssp585  

我想要绘制数据,显示每个周期和季节的一个框,按场景以颜色分隔。每个框将由其平均值(套期保值)、标准差(std)以及潜在的最小和最大范围定义。这个想法是为了展示未来时期将如何改变估计的套期保值分布。我尝试了各种组合:

代码语言:javascript
复制
sns.boxplot(data=df, x="season", y="hedges", hue="model_scenario")

我的错误Could not interpret input 'season'与多索引有关,显然我必须以某种方式对其进行分组或拆分,但这就是我总是失败的地方。对于如何绘制这些数据的建议是值得赞赏的。

EN

回答 1

Stack Overflow用户

发布于 2021-10-24 14:10:27

我假设您的目标是生成如下所示的图形:

因为你已经计算了盒子的盒子图统计信息,所以来自matplotlib的函数sns.boxplot()matplotlib.axes.Axes.boxplot() (它是seaborn后端,在sns.boxplot()内部调用)不再是你可以使用的函数。ax.boxplot()尝试自己计算统计数据,因此这不是可行的方法。

计算完boxplot-statistics之后,matplotlib.axes.Axes.boxplot()调用[matplotlib.axes.Axes.bxp()](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.boxplot.html),这也是一个可以使用的函数。

函数matplotlib.axes.Axes.boxplot()接受一个具有以下命名约定的字典:

  • med:中间值(标量浮点数),
  • q1:第一个四分位数(25%)(标量浮点数),
  • q3:第三个四分位数(75%)(标量浮点数),
  • whislo:下部晶须的下界(标量浮点),
  • whishi:上部晶须的上界(标量浮点),<代码>H218<代码>F219

只需很小的修改,我们就可以重命名或生成所需的DataFrame列。但首先要重置你的多索引。

代码语言:javascript
复制
# df is defined and the multiinde
df = df.rename({'hedges':'med', 'hedges_min':'whislo', 'hedges_max':'whishi'}, axis=1)
df['q1'] = df['med'] - df['hedges_std']
df['q3'] = df['med'] + df['hedges_std']
df['label'] = df.apply(lambda x: '('+ x['period'] +' , '+ x['season'] + ')', axis=1)
df = df[['med', 'whislo','whishi','q1','q3', 'label']] # this are the columns we need

>>> df.head(5)
        med    whislo    whishi        q1        q3                 label
0  0.864328  0.124708  1.760912  0.562580  1.166076  (2021-2025 , winter)
1  0.740410  0.049319  1.189956  0.537447  0.943373  (2021-2025 , spring)
2  0.526264  0.162856  0.662142  0.420514  0.632014  (2021-2025 , summer)
3  0.531141  0.388827  0.687793  0.484863  0.577419    (2021-2025 , fall)
4  1.715075  0.582819  2.423660  1.341209  2.088941  (2025-2050 , winter)

我决定创建一个结合了periodseason的标签。每个标签出现两次,每个model_scenario恰好出现一次。

这是我如何创建上图的代码。它不是完美的,但它展示了它是如何工作的。其中一些部分与sns.boxplot()的代码有关。

代码语言:javascript
复制
from matplotlib import rcParams
import matplotlib.pyplot as plt

colors = ['lightblue', 'olive']
model_scenario = ["ssp245", "ssp585"]
fig, ax = plt.subplots(figsize=(9, 4))
ax.set_title('box plot')

x_tick_label = []
x_tick_position = []
for i, group in enumerate(data_to_plt.groupby('label')):
    for j in range(group[1].shape[0]):
        x_tick_label.append(group[0])
        x_tick_position.append(i)
        if j ==0:
            p = i - 0.15
        else:
            p = i + 0.15
        artist_dict  = ax.bxp(
            bxpstats=[group[1].drop('label', axis=1).iloc[j].to_dict()], 
            showfliers=False, 
            patch_artist=True,
            positions=[p]
        )
        for box in artist_dict["boxes"]:
            box.update(dict(facecolor=colors[j],
                            zorder=.9,
                            edgecolor='gray',
                            linewidth=rcParams["lines.linewidth"])
            )
        if i == 0:
            rect = plt.Rectangle([0,0], 0, 0,
                                 linewidth=0,
                                 edgecolor='gray',
                                 facecolor=colors[j],
                                 label=model_scenario[j])
            ax.add_patch(rect)
            

ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.xticks(x_tick_position, x_tick_label, rotation = 90)

总结一下我对matplotlib所做的工作:

我使用labels

  • I为图例生成标签,我使用bxp()

  • I
  1. model_scenario

x-

来绘制方框

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69666621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档