【问题标题】:Create dynamic updated graph with Python使用 Python 创建动态更新图
【发布时间】:2011-08-02 21:09:30
【问题描述】:

我需要你的帮助,用 Python 编写一个脚本,该脚本将获取动态变化的数据,这里的数据源无关紧要,并在屏幕上显示图形。

我知道如何使用 matplotlib,但 matplotlib 的问题是,我只能在脚本末尾显示一次图形。我不仅需要能够显示一次图表,而且还需要在每次数据更改时即时更新它。

我发现可以使用 wxPython 和 matplotlib 来执行此操作,但对我来说执行此操作有点复杂,因为我根本不熟悉 wxPython。

因此,如果有人向我展示如何使用 wxPython 和 matplotlib 来显示和更新简单图形的简单示例,我将非常高兴。 或者,如果有其他方法可以做到这一点,那对我也有好处。

PS:
好的,因为没有人回答并查看@janislaw 注意到的 matplotlib 帮助并编写了一些代码。这是一些虚拟示例:


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()

此实现存在问题,例如,如果您尝试移动窗口,脚本会停止。不过基本可以用。

【问题讨论】:

  • 我今天只是想这样做并放弃了 matplotlib。我刚刚决定通过套接字将所有数据发送到执行所有绘图的处理脚本,但这可能不是您希望的答案。
  • matplotlib 可以轻松嵌入到您喜欢的任何 GUI 中,并且不需要是静态的。 docs 中有示例 - 请参阅用户界面部分。还有traits/traitsgui/chaco,可能更适合这种工作,但需要范式转变link

标签: python dynamic graph


【解决方案1】:

作为 matplotlib 的替代品,Chaco 库提供了出色的绘图功能,并且在某些方面更适合实时绘图。

查看一些屏幕截图here,尤其是这些示例:

Chaco 有 qt 和 wx 的后端,因此它在大多数情况下都能很好地为您处理底层细节。

【讨论】:

  • 已更新。也就是说,自此答案以来,Python 生态系统中有 许多 新库:BokehAltairHoloviews 等。
【解决方案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()

【讨论】:

  • 我无法让您的解决方案正常工作,因为我是 Tkinter 的新手,我不确定出了什么问题,但到目前为止我发现主循环不能在线程中。跨度>
【解决方案3】:

您可以使用matplotlib.pyplot.show(block=False) 而不是matplotlib.pyplot.show()。此调用不会阻止程序进一步执行。

【讨论】:

    【解决方案4】:

    动态绘图示例,秘诀是在绘图时暂停,这里我使用networkx:

        G.add_node(i,)
        G.add_edge(vertic[0],vertic[1],weight=0.2)
        print "ok"
        #pos=nx.random_layout(G)
        #pos = nx.spring_layout(G)
        #pos = nx.circular_layout(G)
        pos = nx.fruchterman_reingold_layout(G)
    
        nx.draw_networkx_nodes(G,pos,node_size=40)
        nx.draw_networkx_edges(G,pos,width=1.0)
        plt.axis('off') # supprimer les axes
    
        plt.pause(0.0001)
        plt.show()  # display
    

    【讨论】:

      【解决方案5】:

      我需要创建一个随时间更新的图表。我想出的最方便的解决方案是每次都创建一个新图表。问题是在创建第一个图表后,脚本不会执行除非手动关闭窗口。 通过打开交互模式避免了这个问题,如下所示

          for i in range(0,100): 
            fig1 = plt.figure(num=1,clear=True) # a figure is created with the id of 1
            createFigure(fig=fig1,id=1) # calls a function built by me which would insert data such that figure is 3d scatterplot
            plt.ion() # this turns the interactive mode on
            plt.show() # create the graph
            plt.pause(2) # pause the script for 2 seconds , the number of seconds here determine the time after that graph refreshes
      

      这里有两点需要注意

      1. 图形的 id - 如果图形的 id 发生变化,每次都会创建一个新图形,但如果相同,则相关图形将被更新。
      2. 暂停功能 - 这会在指定的时间段内停止代码执行。如果不应用,图表几乎会立即刷新

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多