我在 Matplotlib 中有两个不同的动画子图,我想并行更新它们 - 每个子图都应该提供有关对象的一些信息,我将简称为state
. 该state
对象每帧执行一个阶跃函数。我已经有了第一个使用 blitting 的子图,但我相信我必须每帧完全重新绘制第二个子图,因为它是饼图的形式。
使用我当前的代码,第一个子图 ,plot1
动画效果很好,但第二个子图plot2
, 仅渲染第一帧并且在那之后不更新,即使我在pie_plot
方法中反复调用该full_step
方法。
我在研究此问题时看到的一个可能原因是,如果我不将动画类存储在变量中,它可能会被垃圾收集。这可能与我的问题有关,但是将计时器分配给变量ani
似乎没有做任何事情。我还通过重复调用的打印语句以及每次更改pie_plot
的内容进行了验证。state
我在下面包含了代码,试图在不遗漏相关细节的情况下尽可能地简化和泛化它。为什么可能plot2
无法更新?
def loop(state):
figure, (plot1, plot2) = plt.subplots(1, 2, figsize=(10, 5))
for x, y in state.get_circle_locs():
plot1.add_artist(Circle((x, y)))
figure.canvas.draw()
background = [figure.canvas.copy_from_bbox(simulation_plot.bbox)]
# create changing polygon artist, which will update during blit on plot 1
changing_poly = Circle(state.pos)
changing_poly.set_zorder(10)
plot1.add_artist(changing_poly)
listener_id = [None]
def safe_draw():
canvas = figure.canvas
if listener_id[0]:
canvas.mpl_disconnect(listener_id[0])
canvas.draw()
listener_id[0] = canvas.mpl_connect("draw_event", grab_background)
def grab_background(event=None):
changing_poly.set_visible(False)
safe_draw()
background[0] = figure.canvas.copy_from_bbox(figure.bbox)
changing_poly.set_visible(True)
blit()
def blit():
figure.canvas.restore_region(background[0])
plot1.draw_artist(changing_poly)
figure.canvas.blit(plot1.bbox)
listener_id[0] = figure.canvas.mpl_connect("draw_event", grab_background)
figure_restore = figure.canvas.restore_region
figure_blit = figure.canvas.blit
def pie_plot():
some_pie_chart_data = state.get_some_pie_chart_data()
# calculate parameters for the pie chart
plot2.pie(
bin_percentages, colors=colors, labels=labels,
autopct=make_autopct(bin_percentages))
def full_step():
figure_restore()
state.step()
pie_plot(plot2)
pp_lookahead_polygon.set(center=bike.get_nav_lookahead())
simulation_plot.draw_artist(pp_lookahead_polygon)
figure_blit(plot1.bbox)
ani = figure.canvas.new_timer(interval=1, callbacks=[(full_step, [], {})]).start()
plt.show()