#python #pandas #dataframe #matplotlib
#python #pandas #фрейм данных #matplotlib
Вопрос:
У меня есть фрейм данных pandas, в котором есть несколько столбцов с данными и один столбец, который кодирует состояние интересующего процесса (непоследовательные целые числа).
Вместо отображения столбца состояния в виде строки я хотел бы использовать его для добавления тени к фону графика, например, следующим образом:
Пример фрейма данных:
df = pd.DataFrame(
{
"y": [x * x / 100 for x in range(10)],
"state": [0 if x < 5 else 1 for x in range(10)],
})
y state
0 0.00 0
1 0.01 0
2 0.04 0
3 0.09 0
4 0.16 0
5 0.25 1
6 0.36 1
7 0.49 1
8 0.64 1
9 0.81 1
Желаемый график (обратите внимание, что состояние включено в виде линии, чтобы передать точку, на финальном рисунке я бы, конечно, опустил его):
Ответ №1:
Вы можете найти блоки, где state
значение постоянное, а затем использовать axvspan
для заливки этих блоков разными цветами:
fig, ax = plt.subplots(1)
ax.set_ylim(0,1)
df[['y']].plot(ax=ax)
x = df.loc[df['state'] != df['state'].shift(1), 'state'].reset_index()
x['next_index'] = x['index'].shift(-1).fillna(df.index.max())
for i in x.index:
c = 'blue' if (x.at[i, 'state']==1) else 'red'
xa = x.at[i, 'index']
xb = x.at[i, 'next_index']
ax.axvspan(xa, xb, alpha=0.15, color=c)
Вывод:
Комментарии:
1. Спасибо. В принципе, это работает. Хотя я немного изменил это. Вместо ax.fill_between() Я использую ax.axvspan(), поскольку это охватывает весь диапазон y, а не только то, что ниже y1. Кроме того, в итоге я использовал другой метод для генерации x DataFrame.
2. О, да, я думаю, вы правы,
axvspan()
на самом деле лучше! Позвольте мне обновить это в моем ответе3. Кстати, что вы изменили для
x
вычисления?4. Я привел полный пример здесь: ColorPlot.py