我有一个Python程序( main.py ),它有一个由RTStreamer类处理的恒定数据流,它基本上通过实时流获取数据并附加它到一个numpy数组。然而,我想实际可视化数据,因为它正在进入tkinter和matplotlib进来。在另一个python文件( gui.py )我有一个使用matplotlib动画和一个按钮的实时情节触发我的第一个文件( main.py )以开始流式传输数据。但是,当我单击按钮开始流式传输数据时,我可以在我的控制台上看到它正在获取数据并将其附加到数组(因为我正在打印数组),但图表根本没有更新。
以下是我的 main.py 的简化版本:
closeBidArray = np.array([])
class RTStreamer(stream.Streamer):
def __init__(self, *args, **kwargs):
super(RTStreamer, self).__init__(*args, **kwargs)
print(datetime.now(), "initialized")
def on_success(self, data):
# get data and append it to closeBidArray
def on_error(self, data):
# disconnect
def run():
stream = RTStreamer()
stream.rates()
这是我的 gui.py 的样子:
import main # in order to get closeBidArray
figure = Figure(figsize=(5,5), dpi=100)
subplot1 = figure.add_subplot(111)
class App(tk.Tk):
# Mostly to do with formatting the window and frames in it
def animate():
subplot1.clear
subplot1.plot(main.closeBidArray)
class MainPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# THIS IS THE BUTTON THAT TRIGGERS TO FUNCTION THAT STREAMS THE DATA:
button1 = tk.Button(text="Hi", command=main.run)
button1.pack()
canvas = FigureCanvasTkAgg(figure, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
app = App()
ani = animation.FuncAnimation(figure, animate, interval=1000)
app.mainloop()
我注意到,如果我按 CTRL + C 来打破程序,它会调整流数据并绘制数组,如果我按 CTRL < / kbd> + C 再次关闭matplotlib窗口。但是,我想流式传输并附加到阵列,同时也绘制它,任何关于如何实现这一点的想法?谢谢。
答案 0 :(得分:0)
要使代码正常工作,您需要在每个帧上绘制艺术家,而不仅仅是显示画布。然而,这将是缓慢的。你真正想做的是,只更新数据,并保持画布不变。为此,你使用blit。下面的最低工作示例。
import numpy as np
import matplotlib.pyplot as plt
def animate(movie):
"""
Animate frames in array using blit.
Arguments:
----------
movie: (time, height, width) ndarray
"""
plt.ion()
fig, ax = plt.subplots(1,1)
# initialize blit for movie axis
img = ax.imshow(np.zeros((movie.shape[1],movie.shape[2])),
interpolation = 'nearest', origin = 'lower', vmin = 0, vmax = 1, cmap = 'gray')
# cache the background
bkg = fig.canvas.copy_from_bbox(ax.bbox)
# loop over frames
raw_input('Press any key to start the animation...')
for t in range(movie.shape[0]):
# draw movie
img.set_data(movie[t])
fig.canvas.restore_region(bkg)
ax.draw_artist(img)
fig.canvas.blit(ax.bbox)
return
if __name__ == "__main__":
movie = np.random.rand(1000, 10, 10)
animate(movie)
pass