使用Matplotlib(Python)设置条形图动画

使用Matplotlib(Python)设置条形图动画,python,matplotlib,Python,Matplotlib,我最近写这篇文章是为了抓取一个日志,并显示其中最常用单词的matplotlib.pyplot.bar图 import re from datetime import datetime from collections import Counter import matplotlib.pyplot as plt from matplotlib import animation def read_log(path, index, separator=chr(9)): data = []

我最近写这篇文章是为了抓取一个日志,并显示其中最常用单词的matplotlib.pyplot.bar图

import re
from datetime import datetime
from collections import Counter

import matplotlib.pyplot as plt
from matplotlib import animation

def read_log(path, index, separator=chr(9)):
    data = []
    my_file = open(path,"r+")
    rows = my_file.readlines()
    for row in rows:
        line = re.sub(r'\r\n|\r|\n','',row, flags=re.M)
        if line != '':
            data.append(line.split(separator)[index])
    my_file.close()
    return Counter(data)

def set_plot(counter_data):
    plt.title('This is a title')
    plt.bar(range(len(counter_data)), list(counter_data.values()), align='center')
    plt.xticks(range(len(counter_data)), list(counter_data.keys()))
    plt.tight_layout()
    plt.show()

counter_data = read_log(r'logfile.txt',2)
print(counter_data)
set_plot(counter_data)
我很想为上述情节制作动画,但我无法掌握
animation.FuncAnimation()

你能帮我吗

我添加了以下几行:

fig = plt.Figure()
animation.FuncAnimation(fig, set_plot(counter_data), frames=20)
并删除了
plt.show()


所以我可以给FuncAnimation一个空的图形(fig)和函数。但它不起作用。编辑:它也不会打印错误。

主要问题是
FuncAnimation
需要一个返回艺术家对象的可调用函数。可调用函数将使用框架参数重复调用

在您的示例中,
set\u plot()
只调用一次。它的返回值(
None
)被传递给
FuncAnimation
。相反,您应该有一个方法,例如
update\u plot()
,它从文件中加载数据,更新条形图并返回条形图。此函数(函数本身)应传递给
FuncAnimation

 animation.FuncAnimation(fig, update_plot, frames=20)

不打电话!注意
update\u plot
后缺少的括号。示例显示了如何执行此操作。

主要问题是
FuncAnimation
需要一个返回艺术家对象的可调用对象。可调用函数将使用框架参数重复调用

在您的示例中,
set\u plot()
只调用一次。它的返回值(
None
)被传递给
FuncAnimation
。相反,您应该有一个方法,例如
update\u plot()
,它从文件中加载数据,更新条形图并返回条形图。此函数(函数本身)应传递给
FuncAnimation

 animation.FuncAnimation(fig, update_plot, frames=20)

不打电话!注意
update\u plot
后缺少的括号。示例显示了如何做到这一点。

似乎您的数据是静态的(您从文件中获取数据一次,并且数据不会更改),因此我不太理解您试图设置动画的内容。但是,您的代码包含需要修复的错误,因此出于演示目的,我将在动画的每个步骤中添加高度增量

第一个错误是在向函数传递参数的方式上。对于参数,您必须使用
fargs
参数,否则在您的版本中,您传递的是函数的结果,而不是函数本身

您必须有一个功能(
animate
在我的版本中,在您的版本中,
set\u plot
)来更新动画每个步骤的绘图。(在您的情况下,每次只需输入相同的数据)

该函数需要接受至少一个参数(
val
),该参数用于my
FuncAnimation
,该参数将从迭代器获得的值传递给其
参数

最后的代码如下所示

import re
from datetime import datetime
from collections import Counter
import matplotlib.pyplot as plt
from matplotlib import animation
# uncomment if using in jupyter notebook
# %matplotlib nbagg 

def read_log(path, index, separator=chr(9)):
    data = []
    my_file = open(path,"r+")
    rows = my_file.readlines()
    for row in rows:
        line = re.sub(r'\r\n|\r|\n','',row, flags=re.M)
        if line != '':
            data.append(line.split(separator)[index])
    my_file.close()
    return Counter(data)

fig = plt.figure()
ax = fig.add_subplot()
counter_data = read_log(r'tmp.csv',2)
plt.title('This is a title')
bar = ax.bar(range(len(counter_data)), list(counter_data.values()), align='center')
plt.xticks(range(len(counter_data)), list(counter_data.keys()))
plt.tight_layout()
plt.ylim((0, 30))


def animate(val, counter_data):
    data = list(counter_data.values())
    for i in range(len(data)):
        bar[i].set_height(data[i]+val)

animation.FuncAnimation(fig, func=animate, frames=20, fargs=[counter_data], save_count=10)
我们得到以下动画:


编辑

对于错误,您可以尝试将动画保存为gif,错误将显示出来

anim = animation.FuncAnimation(fig, func=animate, frames=20, fargs=[counter_data], save_count=10)
anim.save('anim.gif', 'imagemagick')


看起来你们的数据是静态的(你们从文件中获取一次数据,它并没有改变),所以我真的不明白你们想做什么。但是,您的代码包含需要修复的错误,因此出于演示目的,我将在动画的每个步骤中添加高度增量

第一个错误是在向函数传递参数的方式上。对于参数,您必须使用
fargs
参数,否则在您的版本中,您传递的是函数的结果,而不是函数本身

您必须有一个功能(
animate
在我的版本中,在您的版本中,
set\u plot
)来更新动画每个步骤的绘图。(在您的情况下,每次只需输入相同的数据)

该函数需要接受至少一个参数(
val
),该参数用于my
FuncAnimation
,该参数将从迭代器获得的值传递给其
参数

最后的代码如下所示

import re
from datetime import datetime
from collections import Counter
import matplotlib.pyplot as plt
from matplotlib import animation
# uncomment if using in jupyter notebook
# %matplotlib nbagg 

def read_log(path, index, separator=chr(9)):
    data = []
    my_file = open(path,"r+")
    rows = my_file.readlines()
    for row in rows:
        line = re.sub(r'\r\n|\r|\n','',row, flags=re.M)
        if line != '':
            data.append(line.split(separator)[index])
    my_file.close()
    return Counter(data)

fig = plt.figure()
ax = fig.add_subplot()
counter_data = read_log(r'tmp.csv',2)
plt.title('This is a title')
bar = ax.bar(range(len(counter_data)), list(counter_data.values()), align='center')
plt.xticks(range(len(counter_data)), list(counter_data.keys()))
plt.tight_layout()
plt.ylim((0, 30))


def animate(val, counter_data):
    data = list(counter_data.values())
    for i in range(len(data)):
        bar[i].set_height(data[i]+val)

animation.FuncAnimation(fig, func=animate, frames=20, fargs=[counter_data], save_count=10)
我们得到以下动画:


编辑

对于错误,您可以尝试将动画保存为gif,错误将显示出来

anim = animation.FuncAnimation(fig, func=animate, frames=20, fargs=[counter_data], save_count=10)
anim.save('anim.gif', 'imagemagick')


谢谢Grigor,数据仍然是静态的,但是当数据在日志文件中更改时它会“更改”:)它统计一组字符串的出现次数,因此每当日志更新时它都会更改:)谢谢Grigor,数据仍然是静态的,但是,当日志文件中的数据更改时,它会“更改”。)它会计算一组字符串的出现次数,因此每当更新日志时,它都会更改:)