#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, спасибо за ответ, это было именно то решение, которое я искал!