Animating Matplotlib panel - blit leaves old frames behind

烈酒焚心 提交于 2019-12-31 01:53:26

问题


I have a wxPython application which contains a matplotlib panel (courtesy of wxmpl, though I've seen the same with a plain FigureCanvasWxAgg canvas).

I'd want to animate one of the plots in the panel, and in the past I've made similar things happen. The way I'm doing it is the suggested:

  • copy the background
  • plot
  • [...]
  • restore background
  • update line data
  • draw artist
  • blit

The problem is that the plots, instead of being "overwritten" by the background restoring, stay there and the whole things understandably looks a mess.

Some (simplified) code:

fig = self.myPanel.get_figure()
ax_top = fig.add_subplot(211)
ax_bottom = self.fig.add_subplot(212)
canvas = fig.canvas
canvas.draw()
bg_top = canvas.copy_from_bbox(ax_top.bbox)
bg_bottom = canvas.copy_from_bbox(ax_bottom.bbox)
line, = ax_bottom.plot(x, y, 'k', animated=True)

Then, on update:

canvas.restore_region(bg_bottom)
line.set_ydata(new_y)
ax_bottom.draw_artist(line)
canvas.blit(ax_bottom.bbox)

The new line gets drawn (and very fast! :), but for some reason it happens over the old line. Can anybody guess why?


回答1:


Added as an answer, by request :)

Try calling fig.canvas.draw() before calling fig.canvas.copy_from_bbox. The exact behavior depends on the backend, so it will be different on different platforms, but generally speaking you need to draw the canvas before trying to copy things from it.




回答2:


Tested with FigureCanvasWxAgg. I think what happens is that between you initializing the panel and axes and then drawing the axis is moved or resized or something. Try waiting to get those backgrounds until you actually draw, i.e. when you initialize frame/panel:

...
bg_top = None
bg_bottom = None
line, = ax_bottom.plot(x, y, 'k', animated=True)
...

The when you update:

def update(self, evt):
    if bf_top is None:
        bg_top = canvas.copy_from_bbox(ax_top.bbox)
        bg_bottom = canvas.copy_from_bbox(ax_bottom.bbox)
    canvas.restore_region(bg_bottom)
    line.set_ydata(new_y)
    ax_bottom.draw_artist(line)
    canvas.blit(ax_bottom.bbox)



回答3:


You must link a ‘draw_event’ to a new copy of the background. Otherwise the old background will always get on the background you want and you can only get with zoom or pan in the toolbar. It works for me.

Martin.



来源:https://stackoverflow.com/questions/6286731/animating-matplotlib-panel-blit-leaves-old-frames-behind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!