0

我在 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()
4

0 回答 0