Многоцветный линейный график фрейма данных Pandas

#python #numpy #matplotlib #pandas

#python #numpy #matplotlib #pandas

Вопрос:

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

                         temp        winds

2014-06-01 00:00:00     8.754545    0.263636
2014-06-01 01:00:00     8.025000    0.291667
2014-06-01 02:00:00     7.375000    0.391667
2014-06-01 03:00:00     6.850000    0.308333
2014-06-01 04:00:00     7.150000    0.258333
2014-06-01 05:00:00     7.708333    0.375000
2014-06-01 06:00:00     9.008333    0.391667
2014-06-01 07:00:00     10.858333   0.300000
2014-06-01 08:00:00     12.616667   0.341667
2014-06-01 09:00:00     15.008333   0.308333
2014-06-01 10:00:00     17.991667   0.491667
2014-06-01 11:00:00     21.108333   0.491667
2014-06-01 12:00:00     21.866667   0.395238
  

Я хотел бы отобразить эти данные в виде одной строки, где цвет меняется в зависимости от температуры. Например, от светло-красного до темно-красного, чем выше температура.

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

Спасибо за любую помощь!

Ответ №1:

Встроенный plot метод в pandas , вероятно, не сможет этого сделать. Вам нужно извлечь данные и отобразить их с помощью matplotlib .

 from matplotlib.collections import LineCollection
import matplotlib.dates as mpd

x=mpd.date2num(df.index.to_pydatetime())
y=df.winds.values
c=df['temp'].values
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, cmap=plt.get_cmap('copper'), norm=plt.Normalize(0, 10))
lc.set_array(c)
lc.set_linewidth(3)
ax=plt.gca()
ax.add_collection(lc)
plt.xlim(min(x), max(x))
ax.xaxis.set_major_locator(mpd.HourLocator())
ax.xaxis.set_major_formatter(mpd.DateFormatter('%Y-%m-%d:%H:%M:%S'))
_=plt.setp(ax.xaxis.get_majorticklabels(), rotation=70 )
plt.savefig('temp.png')
  

введите описание изображения здесь

Стоит упомянуть о двух проблемах,

  • диапазон цветового градиента регулируется norm=plt.Normalize(0, 10)
  • pandas и matplotlib по-разному отображать временные ряды, что требует df.index преобразования в float перед построением графика. И, изменив major_locators , мы вернем xaxis majorticklabels формат даты и времени.
  • Вторая проблема может вызвать проблему, когда мы хотим отобразить более одной строки (данные будут отображаться в двух отдельных диапазонах x):

     #follow what is already plotted:
    df['another']=np.random.random(13)
    print ax.get_xticks()
    df.another.plot(ax=ax, secondary_y=True)
    print ax.get_xticks(minor=True)
    
    [ 735385.          735385.04166667  735385.08333333  735385.125
      735385.16666667  735385.20833333  735385.25        735385.29166667
      735385.33333333  735385.375       735385.41666667  735385.45833333
      735385.5       ]
    [389328 389330 389332 389334 389336 389338 389340]
      

    Поэтому нам нужно сделать это без .plot() метода pandas :

     ax.twinx().plot(x, df.another)
      

    введите описание изображения здесь

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

    1. Это выглядит великолепно и отлично работает. Не могли бы вы случайно сказать мне, как добавить цветную панель для цветной линии?

    2. Я решил проблему с моей цветовой панелью 🙂 Есть идеи, как добавить вторую строку к такому графику с отдельной осью y? Я только что попробовал df [‘anotherline’].plot (ax = axes, secondary_y = True), но это портит весь график. Даже без secondary_y на графике больше ничего не отображается

    3. Смотрите редактирование, просто необходимо ax.twinx().plot(x, df.another) . Приветствия!