【问题标题】:How do I update the title and data of a matplotlib bar chart animation?如何更新 matplotlib 条形图动画的标题和数据?
【发布时间】:2019-09-27 12:34:57
【问题描述】:

我一直在尝试创建一个水平条形图,其中标题和数据在每一帧中都会发生变化。我遇到的问题是,如果我使用blit=True,数据会更新但标题不会更新。当我使用blit=False 时,标题会改变,但数据不会改变(它只会增加)。

我已经阅读了几十个答案并尝试了所有方法,包括 set_titleset_text 但我处于总体损耗。感谢您的帮助。

%matplotlib
import pandas as pd
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 
import numpy as np 
import csv

people = ('','Jim', 'Dan')
plt.rcdefaults()
fig, ax = plt.subplots()
y_pos = np.arange(len(people))

ax.set_xlim(0,10)
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.invert_yaxis() 
ax.set_xlabel('Skill')
titleList=['Basketball','Hockey']
df=[[0,5,7],[0,4,9]]
title = ax.text(0.5,0.95, "Test", bbox={'facecolor':'w', 'alpha':0.5, 'pad':5},transform=ax.transAxes, ha="center")
def animate(i):
       # Example data
    while i<2:
        ax.set_yticks(y_pos)
        ax.set_yticklabels(people)
        ax.set_xlabel(titleList[i])
        performance=df[i]
        title.set_text(str(titleList[i]))
        line= ax.barh(y_pos, performance, align='center',
                color='blue', ecolor='None')
        return line

ani = animation.FuncAnimation(fig,animate, frames=5, blit=True
                            ,interval=2000,repeat=False)

plt.show() 

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:
    1. 您用frames=5 调用FuncAnimation()animate(i) 将因此尝试通过titleList[i] 设置标签和标题,但它只有2 个条目。尤其是blit=True,这会抛出错误。

    2. 您的animate() 函数返回line;如果我们print(line),我们发现它更像是一个&lt;BarContainer object of 3 artists&gt;而不是一条线,即barh()的三个矩形。您应该将barh() 存储在rects 然后return [rect for rect in rects],参见this question

    完整代码:

    import pandas as pd
    import matplotlib as mpl ## uncomment this if you are running this on a Mac
    mpl.use('TkAgg')         ## and want to use blit=True
    import matplotlib.pyplot as plt 
    import matplotlib.animation as animation 
    import numpy as np 
    import csv
    
    people = ('','Jim', 'Dan')
    plt.rcdefaults()
    fig, ax = plt.subplots()
    y_pos = np.arange(len(people))
    
    ax.set_xlim(0,10)
    ax.set_yticks(y_pos)
    ax.set_yticklabels(people)
    ax.invert_yaxis() 
    ax.set_xlabel('Skill')
    titleList=['Basketball','Hockey']
    df=[[0,5,7],[0,4,9]]
    def animate(i):
       # Example data
        while i<2:
            ax.set_yticks(y_pos)
            ax.set_yticklabels(people)
            ax.set_xlabel(titleList[i])
            performance=df[i]
    
            title = ax.text(0.5,0.95,str(titleList[i]), bbox={'facecolor':'w', 'alpha':0.5, 'pad':5},transform=ax.transAxes, ha="center")
    
            rects = ax.barh(y_pos, performance, align='center',
                    color='blue', ecolor='None')
            return [rect for rect in rects] + [title]
    
    
    ani = animation.FuncAnimation(fig,animate, frames=2, blit=True
                                ,interval=2000,repeat=False)
    
    plt.show() 
    

    【讨论】:

    • 感谢您的回答。 1. 你是对的。我把它定为 5,因为那是真正的大小,但我去掉了标题,以便有一个更紧凑的例子。我已经改变了这一点。 2.我不确定如何将其应用于我的示例。由于 barh 中不存在 set_height 和 set_width,我将把什么指定为 rect。再次感谢您!
    • @Jimmy 我已经用完整的代码更新了我的答案。
    • 再次感谢您。唯一的问题是,因为您使用的是 blit=False,所以当数字(宽度)低于前一帧时,矩形不会更新,这与我之前遇到的问题相同。
    • 然后设置blit=True
    • 那么标题不变。这是最初的困境。需要同时更改矩形和标题。
    猜你喜欢
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多