如何从数据框的列创建动画折线图?
How to create an animated line chart from dataframe's columns?
我有一个名为 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()
我需要遍历数据框,因为无论列数如何,代码都必须正常工作。
这就是我要说的:
它绘制了上面的图像(没有线条)然后引发了以下错误:
AttributeError: 'list' object has no attribute 'set_data'
我对动画不太熟悉,因此非常感谢您的帮助。谁能看出我做错了什么?
[编辑]
我正在寻找这样的动画:
但是每一列都有一行。我不知道如何用多条线构建这样的动画图表。
我知道我必须使用 matplotlib.animation
中的 FuncAnimation
,但我遇到了问题。
我从 this Towards Data Science post 得到这个字符。
您要避免使用 vars
作为变量名,因为它是 Python 中的内置函数。你可以像 for loop below.The 中显示的那样循环遍历列动画可以通过以下方式使用 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)
输出:
我有一个名为 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()
我需要遍历数据框,因为无论列数如何,代码都必须正常工作。
这就是我要说的:
它绘制了上面的图像(没有线条)然后引发了以下错误:
AttributeError: 'list' object has no attribute 'set_data'
我对动画不太熟悉,因此非常感谢您的帮助。谁能看出我做错了什么?
[编辑]
我正在寻找这样的动画:
但是每一列都有一行。我不知道如何用多条线构建这样的动画图表。
我知道我必须使用 matplotlib.animation
中的 FuncAnimation
,但我遇到了问题。
我从 this Towards Data Science post 得到这个字符。
您要避免使用 vars
作为变量名,因为它是 Python 中的内置函数。你可以像 for loop below.The 中显示的那样循环遍历列动画可以通过以下方式使用 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)
输出: