【问题标题】:How to create an animated line chart from dataframe's columns?如何从数据框的列创建动画折线图?
【发布时间】:2020-05-25 20:13:29
【问题描述】:

我有一个名为 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 得到这个字符。

【问题讨论】:

    标签: python matplotlib data-visualization matplotlib-animation


    【解决方案1】:

    您要避免使用 vars 作为变量名,因为它是 Python 中的内置函数。你可以像下面的for循环那样循环列。动画可以通过以下方式使用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)
    

    输出:

    【讨论】:

    • 您好,感谢您抽出宝贵时间提供帮助。但是,它会在 plt.show() 行中引发以下错误:AttributeError: 'NoneType' object has no attribute 'session'。你知道那是什么意思吗?
    • 对我来说,代码在 Python 3.6.9 上运行得非常好。如果您不使用 Jupyter 笔记本,则需要删除 matplotlib.use("nbagg") 行。您得到的错误可能是由于使用nbagg 调用的后端
    • 哦,好的。它在没有matplotlib.use("nbagg") 的情况下工作。谢谢!但是,此动画一次绘制一条线。我正在寻找的是一个动画,它显示了同时绘制的所有线条。你能帮忙吗?
    • 如果您发现此解决方案或任何其他解决方案有帮助并且它解决了您的问题,您需要检查绿色标记。这将有助于将注意力集中在未回答的问题上。
    • 嘿,再次感谢您的帮助,但这并不是我想要的。请参阅帖子中的编辑。感谢您为提供帮助所做的努力。
    猜你喜欢
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 2017-01-08
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多