我有一个多索引的Pandas数据帧,我想要将其绘制为箱线图。这应该很容易做到,但我发现自己无法得到我想要的东西。数据如下所示:
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)以及潜在的最小和最大范围定义。这个想法是为了展示未来时期将如何改变估计的套期保值分布。我尝试了各种组合:
sns.boxplot(data=df, x="season", y="hedges", hue="model_scenario")我的错误Could not interpret input 'season'与多索引有关,显然我必须以某种方式对其进行分组或拆分,但这就是我总是失败的地方。对于如何绘制这些数据的建议是值得赞赏的。
发布于 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()接受一个具有以下命名约定的字典:
只需很小的修改,我们就可以重命名或生成所需的DataFrame列。但首先要重置你的多索引。
# 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)我决定创建一个结合了period和season的标签。每个标签出现两次,每个model_scenario恰好出现一次。
这是我如何创建上图的代码。它不是完美的,但它展示了它是如何工作的。其中一些部分与sns.boxplot()的代码有关。
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
bxp()
model_scenario x-
来绘制方框
https://stackoverflow.com/questions/69666621
复制相似问题