问题
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