【问题标题】:Animating pie chart using FuncAnimation showing last frame only使用 FuncAnimation 动画饼图仅显示最后一帧
【发布时间】:2020-11-08 01:28:38
【问题描述】:

我正在尝试使用 Matplotlib 的 FuncAnimation 函数来更新饼图并制作 gif。我已经问过this question,但并没有太大的吸引力。所以这是我的数据集,一个熊猫系列的列表,我将其称为numbers,如下所示:

[[6.166, 5.976, 3.504, 7.104, 5.14],
 [7.472, 5.888, 3.264, 6.4825, 7.168],
 [7.5716, 9.936, 3.6, 8.536, 2.808],
 [2.604, 2.296, 0.0, 6.144, 4.836],
 [7.192, 4.932, 0.0, 6.016, 8.808],
 [7.192, 5.5755, 3.694, 9.376, 9.108],
 [7.63616, 5.912, 3.968, 6.672, 3.192],
 [3.41049, 5.44, 4.004, 7.212, 3.6954],
 [4.3143, 6.364, 3.584, 7.44, 5.78],
 [4.992, 3.9692, 4.272, 0.0, 2.528]]

这是我正在使用的代码:

colors = ["yellow", "red", "purple", "blue", "green"]
explode = [0.01, 0.01, 0.01, 0.01, 0.01]
labels = ["DM", "Bard", "Warlock", "Paladin", "Ranger"]
z = [0,0,0,0,0]

fig,ax = plt.subplots()

def update(num):
    
    ax.axis('equal')
    global z
    for x in range(0,10):
        z += numbers[x]
        z = z.tolist()
        
        
        
    ax.pie(z, explode=explode, labels=labels, colors=colors, 
            autopct='%1.1f%%', shadow=True, startangle=140)

    ax.set_title(sum(z))    
    
ani = FuncAnimation(fig, update, frames=range(10), repeat=False)
plt.show()

输出:

根据此输出,只有总数会显示在最后一帧中。没有中间动画正在进行。我已阅读 this question 并回答,但我无法弄清楚为什么这不起作用。

【问题讨论】:

    标签: python pandas matplotlib


    【解决方案1】:

    你需要清除update开头的ax,除了我认为这部分

    for x in range(0,10):
        z += numbers[x]
        z = z.tolist()
    

    不正确。试试下面的代码

    import numpy as np
    import matplotlib.animation as animation
    from matplotlib import pyplot as plt 
    
    numbers = [[6.166, 5.976, 3.504, 7.104, 5.14],
     [7.472, 5.888, 3.264, 6.4825, 7.168],
     [7.5716, 9.936, 3.6, 8.536, 2.808],
     [2.604, 2.296, 0.0, 6.144, 4.836],
     [7.192, 4.932, 0.0, 6.016, 8.808],
     [7.192, 5.5755, 3.694, 9.376, 9.108],
     [7.63616, 5.912, 3.968, 6.672, 3.192],
     [3.41049, 5.44, 4.004, 7.212, 3.6954],
     [4.3143, 6.364, 3.584, 7.44, 5.78],
     [4.992, 3.9692, 4.272, 0.0, 2.528]]
    numbers = np.array(numbers)
    
    colors = ["yellow", "red", "purple", "blue", "green"]
    explode = [0.01, 0.01, 0.01, 0.01, 0.01]
    labels = ["DM", "Bard", "Warlock", "Paladin", "Ranger"]
    z = np.array([0,0,0,0,0]).astype(np.float)
    
    fig,ax = plt.subplots()
    
    def update(num):
        
        global z
        
        ax.clear()
        ax.axis('equal')     
        z += numbers[num]  
        pie = ax.pie(z, explode=explode, labels=labels, colors=colors, 
                     autopct='%1.1f%%', shadow=True, startangle=140)
        ax.set_title(sum(z))    
        
    ani = animation.FuncAnimation(fig, update, frames=range(10), repeat=False)
    ani.save('test.gif', writer='pillow', fps=1)
    

    输出是

    【讨论】:

    • 这正是我一直在尝试做的,非常感谢您的帮助。我很高兴这是在没有那个 for 循环的情况下完成的,这让我发疯了。您能帮我解释一下num 在更新功能中的工作原理吗?看了文档后,我想不通。
    • @m00saca 不客气 :) numanimation.FuncAnimation 传递给函数 update 的参数。由于frames=range(10)animation.FuncAnimation 会将 10 个整数(帧的索引)传递给函数update
    • @m00saca num 不是一个迭代器,它是FuncAnimation 会将frames 中的项目迭代地传递给函数update。 :)
    • @m00saca 不知道,因为第一帧的索引是0(可以在函数update里面打印num看这个),所以数组的第一行会加数字零数组 z。因此,第一帧应该对应数组编号的第一行。
    • @m00saca 不客气,我之前没有注意到这种行为,谢谢! :) 你的新帖子有一个答案,看起来它会解决这个问题。
    猜你喜欢
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    相关资源
    最近更新 更多