用Python创建动态更新图表
我需要写一个Python脚本,这个脚本可以处理动态变化的数据,数据的来源在这里不重要,然后在屏幕上显示图表。
我知道怎么用matplotlib这个库,但问题是我只能在脚本结束时显示一次图表。我希望不仅能显示一次图表,还能在数据每次变化时实时更新它。
我发现可以用wxPython和matplotlib结合来实现这个功能,但对我来说这有点复杂,因为我对wxPython完全不熟悉。
所以如果有人能给我一个简单的例子,教我怎么用wxPython和matplotlib来显示和更新简单的图表,我会非常开心。如果有其他方法也可以做到这一点,那对我来说也很好。
更新
附注:因为没有人回答,我查看了matplotlib的帮助文档,受到了@janislaw的启发,写了一些代码。这是一个简单的例子:
import time
import matplotlib.pyplot as plt
def data_gen():
a=data_gen.a
if a>10:
data_gen.a=1
data_gen.a=data_gen.a+1
return range (a,a+10)
def run(*args):
background = fig.canvas.copy_from_bbox(ax.bbox)
while 1:
time.sleep(0.1)
# restore the clean slate background
fig.canvas.restore_region(background)
# update the data
ydata = data_gen()
xdata=range(len(ydata))
line.set_data(xdata, ydata)
# just draw the animated artist
ax.draw_artist(line)
# just redraw the axes rectangle
fig.canvas.blit(ax.bbox)
data_gen.a=1
fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot([], [], animated=True)
ax.set_ylim(0, 20)
ax.set_xlim(0, 10)
ax.grid()
manager = plt.get_current_fig_manager()
manager.window.after(100, run)
plt.show()
这个实现有一些问题,比如如果你试图移动窗口,脚本会停止。但基本上它是可以用的。
6 个回答
0
你可以用 matplotlib.pyplot.show(block=False)
来代替 matplotlib.pyplot.show()
。这样做的好处是,它不会让程序停下来,而是可以继续执行后面的代码。
2
这是我写的一个类,用来解决这个问题。它可以接收你传给它的matplotlib图形,并把它放到一个图形用户界面(GUI)窗口里。这个类在自己的线程中运行,这样即使你的程序在忙,它也能保持响应。
import Tkinter
import threading
import matplotlib
import matplotlib.backends.backend_tkagg
class Plotter():
def __init__(self,fig):
self.root = Tkinter.Tk()
self.root.state("zoomed")
self.fig = fig
t = threading.Thread(target=self.PlottingThread,args=(fig,))
t.start()
def PlottingThread(self,fig):
canvas = matplotlib.backends.backend_tkagg.FigureCanvasTkAgg(fig, master=self.root)
canvas.show()
canvas.get_tk_widget().pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)
toolbar = matplotlib.backends.backend_tkagg.NavigationToolbar2TkAgg(canvas, self.root)
toolbar.update()
canvas._tkcanvas.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)
self.root.mainloop()
在你的代码中,你需要这样初始化绘图工具:
import pylab
fig = matplotlib.pyplot.figure()
Plotter(fig)
然后你可以这样进行绘图:
fig.gca().clear()
fig.gca().plot([1,2,3],[4,5,6])
fig.canvas.draw()
2
作为matplotlib的替代品,Chaco库提供了很不错的绘图功能,在某些方面更适合实时绘图。
你可以在这里查看一些截图,特别是看看这些例子:
Chaco支持qt和wx这两种后台,所以大部分时候,它会帮你处理好底层的细节。