Python matplotlib 调用 savefig 后更新图形

发布于 2024-10-17 18:18:27 字数 1348 浏览 7 评论 0原文

我的问题是: 我在 PyGTK 应用程序中有 Matplotlib 图,它每隔几秒就会不断更新。我添加了将图形作为 PNG 文件保存到磁盘的功能。调用figure.savefig(文件名,其他参数)后,我在应用程序中的图形停止更新。

图初始化阶段:

# setup matplotlib stuff on empty space in vbox4
    figure = Figure()
    canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea
    canvas.show()
    self.win.get_widget('vbox4').pack_start(canvas, True, True) # this will be aded to last place
    self.win.get_widget('vbox4').reorder_child(canvas, 1) #place plot to space where it should be

图正在以这种方式更新(这在单独的线程中每隔几秒调用一次):

def _updateGraph(self, fig, x, x1, y):
    #Various calculations done here

    fig.clf()#repaint plot: delete current and formate a new one
    axis = fig.add_subplot(111)
    #axis.set_axis_off()
    axis.grid(True)
#remove ticks and labels
    axis.get_xaxis().set_ticks_position("none")
    for i in range(len(axis.get_xticklabels())): axis.get_xticklabels()[i].set_visible(False)
    axis.get_yaxis().set_ticks_position("none")
    axis.plot(numpy.array(x),numpy.array(y)/(1.0**1), "k-" ,alpha=.2)
    axis.set_title('myTitle')
    fig.autofmt_xdate()
    fig.canvas.draw()

一切都按预期进行。但是调用后:

figure.savefig(fileName, bbox_inches='tight', pad_inches=0.05)

文件已保存,但是屏幕上的图形停止更新

有什么想法如何将图形保存到磁盘并仍然能够在屏幕上更新我的图形?

My problem is:
I have Matplotlib figure in PyGTK application, that is constatly updated each few seconds. I've added abbility to save figure to disk as PNG file. After calling figure.savefig(filename, other parameters) my figure in application stops being updated.

Figure initialization phase:

# setup matplotlib stuff on empty space in vbox4
    figure = Figure()
    canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea
    canvas.show()
    self.win.get_widget('vbox4').pack_start(canvas, True, True) # this will be aded to last place
    self.win.get_widget('vbox4').reorder_child(canvas, 1) #place plot to space where it should be

Figure is being updated this way (this called each few seconds in separate thread):

def _updateGraph(self, fig, x, x1, y):
    #Various calculations done here

    fig.clf()#repaint plot: delete current and formate a new one
    axis = fig.add_subplot(111)
    #axis.set_axis_off()
    axis.grid(True)
#remove ticks and labels
    axis.get_xaxis().set_ticks_position("none")
    for i in range(len(axis.get_xticklabels())): axis.get_xticklabels()[i].set_visible(False)
    axis.get_yaxis().set_ticks_position("none")
    axis.plot(numpy.array(x),numpy.array(y)/(1.0**1), "k-" ,alpha=.2)
    axis.set_title('myTitle')
    fig.autofmt_xdate()
    fig.canvas.draw()

everything works as expected. But after calling:

figure.savefig(fileName, bbox_inches='tight', pad_inches=0.05)

File have been saved, BUT my figure on screen stops being updated.

Any ideas how do I save figure to disk and still be able to update my fig on screen ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我偏爱纯白色 2024-10-24 18:18:27

您是否尝试过更新线条数据而不是重新创建图形?这假设数据点的数量不会改变每帧。它可能有助于解决拒绝更新的问题,至少会更快。

def _updateGraph(self, fig, x, x1, y): 
    #Various calculations done here 


    ydata = numpy.array(y)/(1.0**1)

    # retrieved the saved line object
    line = getattr(fig, 'animated_line', None);

    if line is None:
        # no line object so create the subplot and axis and all 
        fig.clf()
        axis = fig.add_subplot(111) 

        axis.grid(True) 
        #remove ticks and labels 
        axis.get_xaxis().set_ticks_position("none") 
        for i in range(len(axis.get_xticklabels())): 
            axis.get_xticklabels()[i].set_visible(False) 
        axis.get_yaxis().set_ticks_position("none")             
        xdata = numpy.array(x);
        line = axis.plot(xdata, ydata, "k-" ,alpha=.2) 
        axis.set_title('myTitle') 
        fig.autofmt_xdate() 

        # save the line for later reuse
        fig.animated_line = line
    else:
        line.set_ydata(ydata)
    fig.canvas.draw() 

Have you tried updating the line data instead of recreating the figure? This assumes the number of datapoints doesn't change each frame. It might help issue of things refusing to update, and at the least it will be faster.

def _updateGraph(self, fig, x, x1, y): 
    #Various calculations done here 


    ydata = numpy.array(y)/(1.0**1)

    # retrieved the saved line object
    line = getattr(fig, 'animated_line', None);

    if line is None:
        # no line object so create the subplot and axis and all 
        fig.clf()
        axis = fig.add_subplot(111) 

        axis.grid(True) 
        #remove ticks and labels 
        axis.get_xaxis().set_ticks_position("none") 
        for i in range(len(axis.get_xticklabels())): 
            axis.get_xticklabels()[i].set_visible(False) 
        axis.get_yaxis().set_ticks_position("none")             
        xdata = numpy.array(x);
        line = axis.plot(xdata, ydata, "k-" ,alpha=.2) 
        axis.set_title('myTitle') 
        fig.autofmt_xdate() 

        # save the line for later reuse
        fig.animated_line = line
    else:
        line.set_ydata(ydata)
    fig.canvas.draw() 
感受沵的脚步 2024-10-24 18:18:27

我已经找到了解决这个问题的方法。由于我的图形在调用 figure.savefig() 后拒绝更新,所以我找到了一种解决它的方法。我的图位于 HBox2 容器中(GUI 是使用 Glade 3.6.7 创建的)作为第一个元素,

#   some stuff going
    figure.saveFig(fileName)
#   WORK-A-ROUND: delete figure after calling savefig()
    box = self.win.get_widget('hbox2')
    box.remove(box.get_children()[0])
    self._figPrepare()

def _figPrepare(self):  #initialize graph
    figure = Figure()
    canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea
    canvas.show()       
    figure.clf()
    gui.w().set("figure", figure)
    self.win.get_widget('hbox2').pack_start(canvas, True, True) # this will be aded to last place
    self.win.get_widget('hbox2').reorder_child(canvas, 0) #place plot to space where it should be

我知道这不是最佳实践,而且可能很慢,但对我来说效果还不错。希望其他人会发现这很有用

I have found a work-a-round to this. As my figure refuses to be updated after calling figure.savefig() so i found a way how to work a round it. My figure is within HBox2 container (GUI is created with Glade 3.6.7) as first element

#   some stuff going
    figure.saveFig(fileName)
#   WORK-A-ROUND: delete figure after calling savefig()
    box = self.win.get_widget('hbox2')
    box.remove(box.get_children()[0])
    self._figPrepare()

def _figPrepare(self):  #initialize graph
    figure = Figure()
    canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea
    canvas.show()       
    figure.clf()
    gui.w().set("figure", figure)
    self.win.get_widget('hbox2').pack_start(canvas, True, True) # this will be aded to last place
    self.win.get_widget('hbox2').reorder_child(canvas, 0) #place plot to space where it should be

I know this is not best practice, and probably is slow, but it work OK for me. Hope someone else will find this useful

残花月 2024-10-24 18:18:27

来自 http://matplotlib.org/examples/user_interfaces/embedding_in_gtk2.html

似乎是什么帮助是“agg”,不确定这意味着什么,但为我修复了这个错误:)

from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas

from http://matplotlib.org/examples/user_interfaces/embedding_in_gtk2.html

what seems to help is the "agg" not sure what that means but fixed this bug for me :)

from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文