Как создать анимированный линейный график из столбцов фрейма данных? - PullRequest
0 голосов
/ 25 мая 2020

У меня есть этот фрейм данных под названием vars, и я пытаюсь построить анимированную линейную диаграмму, в которой каждый столбец представляет собой одну строку (кроме столбца даты, который будет осью x).

 data      var_brl  var_ars var_bob var_clp var_cop var_mxn var_pen var_pyg var_uyu
0   01/01/2020  0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
1   02/01/2020  0.17    -0.10   0.14    -0.36   -1.01   -0.49   -0.41   0.41    0.16
2   03/01/2020  1.19    -0.22   0.07    1.65    -1.01   -0.04   0.11    0.49    -0.38
3   04/01/2020  1.19    -0.22   0.07    1.65    -1.01   -0.04   0.11    0.49    -0.38
4   05/01/2020  1.19    -0.22   0.07    1.65    -1.01   -0.04   0.11    0.49    -0.38
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
135 15/05/2020  45.71   13.03   -0.07   10.07   18.98   26.43   3.78    1.81    18.19
136 16/05/2020  45.71   13.03   -0.07   10.07   18.98   26.43   3.78    1.81    18.19
137 17/05/2020  45.71   13.03   -0.07   10.07   18.98   26.43   3.78    1.81    18.19
138 18/05/2020  42.32   13.28   0.00    8.92    17.20   25.49   3.47    2.09    18.06
139 19/05/2020  43.20   13.43   0.00    8.88    16.69   25.08   3.46    2.10    18.06

Это код, который я использую:

fig, ax = plt.subplots(figsize=(16, 8))

plt.style.use('ggplot')

months = mdates.MonthLocator()
months_fmt = mdates.DateFormatter('%m/%Y')

ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(months_fmt)

limx_i = vars.iloc[0, 0]
limx_f = vars.iloc[-1, 0]
limy_f = vars.iloc[:, 1:].max().max()
limy_i = vars.iloc[:, 1:].min().min()

ax.set_xlim(limx_i, limx_f + dt.timedelta(days=30))
ax.set_ylim(limy_i, limy_f)

line, = [ax.plot([], [], lw=2)]
for i in range(1, vars.shape[1]):

    def animate(i):
        line.set_data(vars['data'], vars.iloc[:, i])
        return line,

ani = animation.FuncAnimation(fig, animate, frames=140, interval=20, blit=True)

ax.tick_params(bottom=False, top=False, right=False, left=False)
ax.set_ylabel('Oscilação acumulada %')
plt.grid(False)

for key, spine in ax.spines.items():
    spine.set_visible(False)

plt.tight_layout()
plt.show()

Мне нужно перебрать фрейм данных, потому что код должен работать независимо от количества столбцов.

Это насколько я ' m идет: enter image description here

Он отображает изображение выше (без линий), а затем вызывает следующую ошибку:

AttributeError: 'list' object has no attribute 'set_data'

У меня нет опыта работы с анимацией, поэтому любая помощь будет очень благодарна. Может кто-нибудь увидит, что я делаю не так?

[EDIT]

Я ищу такую ​​анимацию:

enter image description here

Но со строчкой для каждого столбца. И я не могу понять, как построить такую ​​анимированную диаграмму с несколькими линиями.

Я понимаю, что мне нужно использовать FuncAnimation из matplotlib.animation, но у меня проблемы с этим.

Я получил этот символ из сообщения Towards Data Science .

1 Ответ

1 голос
/ 26 мая 2020

Вы не хотите использовать vars в качестве имени переменной, потому что это встроенная функция в Python. Вы можете l oop поверх столбцов, как показано ниже для l oop. Анимация может быть достигнута с помощью интерактивного режима matplotlib следующим образом:

import pandas as pd
from datetime import date, datetime, timedelta

import matplotlib.pyplot as plt
import matplotlib.dates as md
# test file 
df = pd.read_csv('test.txt',sep='\s+')
def convert_date(df):
    return datetime.strptime(df['data'], '%d/%m/%Y')
df['data'] = df.apply(convert_date, axis=1)
fig, ax = plt.subplots()



limx_i = df.iloc[0, 0]
limx_f = df.iloc[-1, 0]
limy_f = df.iloc[:, 1:].max().max()
limy_i = df.iloc[:, 1:].min().min()

ax.set_xlim(limx_i, limx_f)
ax.set_ylim(limy_i, limy_f)
plt.ion()   # set interactive mode
plt.show()

for i,row in df.iterrows():
    plt.cla()
    df.iloc[:i+1,:].plot(x='data', ax=ax)
    ax.set_xlim(limx_i, limx_f)
    ax.set_ylim(limy_i, limy_f)
    plt.legend(loc='upper right')
    plt.gcf().canvas.draw()
    plt.pause(0.1)

Вывод: enter image description here

...