Отображение среднегодового значения и стандартного отклонения разными цветами для каждого года

#pandas #matplotlib #pandas-groupby

#pandas #matplotlib #pandas-groupby

Вопрос:

У меня есть данные за несколько лет. Я рассчитал среднее значение и стандартное отклонение для каждого года. Теперь я хочу отобразить каждую строку со средним значением в виде точечной диаграммы и заполнить график между стандартными отклонениями, то есть средним значением плюс минус стандартное отклонение, разными цветами за разные годы.

После использования 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
  

Ответ №1:

Это очень хороший вопрос, который вы задали, и на него не было простого ответа. Но если я правильно понял проблему, вам нужен график заливки разными цветами для каждого года. Верхняя и нижняя границы графика будут находиться между средним std и средним — std?

Итак, я сформировал пользовательский временной ряд, и вот как я отобразил значения с верхней и нижней границами:

 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) amp; (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
  

И график выглядит следующим образом:
введите описание изображения здесь

Дайте мне знать, если это поможет! 🙂

Комментарии:

1. Привет @Aditya, спасибо за ответ, это было именно то решение, которое я искал!