首页 > 解决方案 > 以不同颜色绘制每年的年均值和标准差

问题描述

我有几年的数据。我计算了每年的平均值和标准差。现在我想用平均值绘制每一行作为散点图,并在标准差之间填充图,即不同年份不同颜色的平均值加减标准差。

使用df_wc.set_index('Date').resample('Y')["Ratio(a/w)"].mean()它后,它只返回一年中的最后一个日期(如下面的数据集中所示),但我希望标准差的填充图能够传播到全年。

样本数据集:

   Date    |  Mean   |  Std_dv
1858-12-31  1.284273   0.403052
1859-12-31  1.235267   0.373283
1860-12-31  1.093308   0.183646
1861-12-31  1.403693   0.400722

标签: pandasmatplotlibpandas-groupby

解决方案


你问的这个问题很好,但没有一个简单的答案。但如果我正确理解了这个问题,你需要一个每年都有不同颜色的填充图。绘图的上限和下限将在均值 + 标准和均值 - 标准之间?

因此,我形成了一个自定义时间序列,这就是我绘制具有上限和下限的值的方式:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection,PatchCollection
from matplotlib.colors import ListedColormap, BoundaryNorm
import pandas as pd

ts = range(10)
num_classes = len(ts)

df = pd.DataFrame(data={'TOTAL': np.random.rand(len(ts)), 'Label': list(range(0, num_classes))}, index=ts)
df['UB'] = df['TOTAL'] + 2
df['LB'] = df['TOTAL'] - 2
print(df)

colors = ['r', 'g', 'b', 'y',  'purple', 'orange', 'k', 'pink', 'grey', 'violet']
cmap = ListedColormap(colors)
norm = BoundaryNorm(range(num_classes+1), cmap.N)

points = np.array([df.index, df['TOTAL']]).T.reshape(-1, 1, 2)
pointsUB = np.array([df.index, df['UB']]).T.reshape(-1, 1, 2)
pointsLB = np.array([df.index, df['LB']]).T.reshape(-1, 1, 2)

segments = np.concatenate([points[:-1], points[1:]], axis=1)
segmentsUB = np.concatenate([pointsUB[:-1], pointsUB[1:]], axis=1)
segmentsLB = np.concatenate([pointsLB[:-1], pointsLB[1:]], axis=1)

lc = LineCollection(segments, cmap=cmap, norm=norm, linestyles='dashed')
lc.set_array(df['Label'])

lcUB = LineCollection(segmentsUB, cmap=cmap, norm=norm, linestyles='solid')
lcUB.set_array(df['Label'])

lcLB = LineCollection(segmentsLB, cmap=cmap, norm=norm, linestyles='solid')
lcLB.set_array(df['Label'])

fig1 = plt.figure()
plt.gca().add_collection(lc)
plt.gca().add_collection(lcUB)
plt.gca().add_collection(lcLB)
for i in range(len(colors)):
    plt.fill_between( df.index,df['UB'],df['LB'], where= ((df.index >= i) & (df.index <= i+1)), alpha = 0.1,color=colors[i]) 
plt.xlim(df.index.min(), df.index.max())
plt.ylim(-3.1, 3.1)
plt.show()

获得的结果数据框如下所示:

      TOTAL  Label        UB        LB
0  0.681455      0  2.681455 -1.318545
1  0.987058      1  2.987058 -1.012942
2  0.212432      2  2.212432 -1.787568
3  0.252284      3  2.252284 -1.747716
4  0.886021      4  2.886021 -1.113979
5  0.369499      5  2.369499 -1.630501
6  0.765192      6  2.765192 -1.234808
7  0.747923      7  2.747923 -1.252077
8  0.543212      8  2.543212 -1.456788
9  0.793860      9  2.793860 -1.206140

情节是这样的: 在此处输入图像描述

让我知道这是否有帮助!:)


推荐阅读