根据 XLS 文件中的年份动画散点图

Animate scatter plot according to year in a XLS file

我正在构建一个从 xls 文件读取数据的简单散点图(预期寿命 x 人均 GDP)。这是代码:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm

#ler a terceira sheet da planilha
data = pd.read_excel('sample.xls', sheet_name=0)
data.head()

plt.scatter(x = data['LifeExpec'],
        y = data['GDPperCapita'],
        s = data['PopX1000'],
        c = data['PopX1000'],
        cmap=cm.viridis,
        edgecolors = 'none',
        alpha = 0.7)

for state in range(len(data['State'])):
    plt.text(x = data['LifeExpec'][state],
         y = data['GDPperCapita'][state],
         s = data['State'][state],
         fontsize = 14)

plt.colorbar()
plt.show()

xls文件:

剧情:

现在我想将其他年份的一些数据添加到此 xls 文件中,并为气泡设置动画,以便它们根据每年的 GDP 和人口数量移动和改变大小。 在一次愚蠢的尝试中,我将代码更改为:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import mplcursors
from matplotlib.animation import FuncAnimation

data = pd.read_excel('sample.xls', sheet_name=0)
data.head()
uniqueYears = data['Year'].unique()

fig, ax = plt.subplots()

def animate(i):
    for i in uniqueYears:
        ax.scatter(x = data['lifeExpec'],
            y = data['GDPperCapita'],
            s = data['PopX1000']/4,
            c = data['Region'].astype('category').cat.codes,
            cmap=cm.viridis,
            edgecolors = 'none',
            alpha = 0.7)

anim = FuncAnimation(fig, animate)

for state in range(len(data['State'])):
    plt.text(x = data['lifeExpec'][state],
             y = data['GDPperCapita'][state],
             s = data['State'][state],
             fontsize = 10,
             ha = 'center',
             va = 'center')

mplcursors.cursor(hover=True)
plt.draw()
plt.show()

我想也许这样做的方法是使用 animate 函数多次构建图表,每年迭代一次。但我无法弄清楚如何 "filter" 有关该特定年份的行。

我是不是太过分了?甚至可以使用 matplotlib 来实现吗?

您可以使用简单的 if 语句过滤行。列出您要绘制的年份,即 list=[2000,2001,2002]。 然后遍历列表

for i in range (0,2):
   if x=list[i]:
      #do whatever you want

其中 x 是 F 列中包含年份的数据。

也可以只按年份保存数字

plt.savefig("{}.png".format(i))

然后只需使用此命令创建动画:

ffmpeg -framerate 25 -i %d.png -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p output.mp4

然后您可以使用 rm *.png

删除保存的地块

您需要在脚本中导入 os 或在脚本创建绘图后通过命令行手动导入。我认为这是解决问题的一种更简单的方法。

干杯

使用 Stylianos Nikas 和 ImportanceOfBeingErnest 所说的内容作为起点,我在数据框中制作了一个包含独特年份的列表,并将其长度用作 FuncAnimation 中的参数,如下所示:

def animate(frames):           
    ax.clear()    
    data = df[df['Ano'] == uniqueYears[frames]]
    ax.scatter(y = data['lifeExpec'],
    x = data['GPDperCapita'],
    s = data['PopX1000']/40000,
    c = data['Region'].astype('category').cat.codes,
    cmap = cm.viridis,
    edgecolors = 'none',
    alpha = 0.5)

anim = FuncAnimation(fig, animate, frames = len(uniqueYears),interval = 200, repeat = False)

为了避免帧重叠,我只是将 ax.clear() 添加到动画函数的开头。