`matplotlib`:艺术家动画状态的目的是什么?
`matplotlib`: what is the purpose of an artist's animated state?
Artists in matplotlib
have methods to set/get their animated state (a boolean). 我似乎找不到文档来解释 "animated state" 变量的用途。你能解释一下,或者给我指点合适的资源吗?
我不确定它是否在任何地方都有完整的记录,但艺术家的动画状态决定了它在绘制情节时是否包含在内。
如果 animated
为 True,则调用 fig.draw()
时不会绘制艺术家。相反,它只会在您手动调用 draw_artist(artist_with_animated_set)
时绘制。这允许简化 blitting 函数。
注意:这并不适用于所有后端!我认为它适用于几乎所有的交互式后端,但不适用于非交互式后端。它旨在与 blitting 结合使用,因此不支持 blitting 的后端不支持动画标志。
例如,如果我们做类似的事情:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(range(10), animated=True)
plt.show()
我们将得到一个空白图 -- 不会绘制线条。 (注意:如果保存此图, 行将 显示出来。请参阅上面关于非交互式后端的警告。Matplotlib 暂时切换到非交互式后端以保存图形。)
要了解这为什么有用,假设您正在制作动画或交互式图形用户界面(并且没有使用新的动画框架)。您需要使用 blitting 使动画出现 "smooth".
但是,无论何时调整图形大小等,都需要更新动画的背景。处理此问题的最佳方法是将回调连接到绘制事件。如果没有 animated
标志,您将不得不在 内部 绘制回调中重新绘制绘图,这将导致无限循环。 (解决方法是断开并重新连接绘制事件回调,但这有点麻烦。)
无论如何,动画标志大大简化了这个过程。例如,您可以在类似于以下的内容中使用 animated
标志:
import numpy as np
import matplotlib.pyplot as plt
class AnimatedSinWave(object):
def __init__(self, speed=0.1, interval=25):
self.fig, self.ax = plt.subplots()
self.x = np.linspace(0, 6 * np.pi, 200)
self.i, self.speed = 0.0, speed
self.line, = self.ax.plot(self.x, np.sin(self.x), animated=True)
self.ax.set_title('Try resizing the figure window')
self.fig.canvas.mpl_connect('draw_event', self.update_background)
self.t = self.fig.canvas.new_timer(interval, [(self.update, [], {})])
self.t.start()
def update_background(self, event):
self._background = self.fig.canvas.copy_from_bbox(self.ax.bbox)
def update(self):
self.fig.canvas.restore_region(self._background)
self.line.set_ydata(np.sin(self.i * self.speed + self.x))
self.ax.draw_artist(self.line)
self.i += 1
self.fig.canvas.blit(self.ax.bbox)
def show(self):
plt.show()
AnimatedSinWave().show()
注意:出于各种原因,OSX 和 qt*Agg 后端会发生一些奇怪的事情。如果 window 第一次弹出时背景是黑色的,移动或聚焦 window,它应该会自行修复。
无论如何,如果没有 animated
标志(或较新的动画框架),该示例将变得 多 复杂。
Artists in matplotlib
have methods to set/get their animated state (a boolean). 我似乎找不到文档来解释 "animated state" 变量的用途。你能解释一下,或者给我指点合适的资源吗?
我不确定它是否在任何地方都有完整的记录,但艺术家的动画状态决定了它在绘制情节时是否包含在内。
如果 animated
为 True,则调用 fig.draw()
时不会绘制艺术家。相反,它只会在您手动调用 draw_artist(artist_with_animated_set)
时绘制。这允许简化 blitting 函数。
注意:这并不适用于所有后端!我认为它适用于几乎所有的交互式后端,但不适用于非交互式后端。它旨在与 blitting 结合使用,因此不支持 blitting 的后端不支持动画标志。
例如,如果我们做类似的事情:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(range(10), animated=True)
plt.show()
我们将得到一个空白图 -- 不会绘制线条。 (注意:如果保存此图, 行将 显示出来。请参阅上面关于非交互式后端的警告。Matplotlib 暂时切换到非交互式后端以保存图形。)
要了解这为什么有用,假设您正在制作动画或交互式图形用户界面(并且没有使用新的动画框架)。您需要使用 blitting 使动画出现 "smooth".
但是,无论何时调整图形大小等,都需要更新动画的背景。处理此问题的最佳方法是将回调连接到绘制事件。如果没有 animated
标志,您将不得不在 内部 绘制回调中重新绘制绘图,这将导致无限循环。 (解决方法是断开并重新连接绘制事件回调,但这有点麻烦。)
无论如何,动画标志大大简化了这个过程。例如,您可以在类似于以下的内容中使用 animated
标志:
import numpy as np
import matplotlib.pyplot as plt
class AnimatedSinWave(object):
def __init__(self, speed=0.1, interval=25):
self.fig, self.ax = plt.subplots()
self.x = np.linspace(0, 6 * np.pi, 200)
self.i, self.speed = 0.0, speed
self.line, = self.ax.plot(self.x, np.sin(self.x), animated=True)
self.ax.set_title('Try resizing the figure window')
self.fig.canvas.mpl_connect('draw_event', self.update_background)
self.t = self.fig.canvas.new_timer(interval, [(self.update, [], {})])
self.t.start()
def update_background(self, event):
self._background = self.fig.canvas.copy_from_bbox(self.ax.bbox)
def update(self):
self.fig.canvas.restore_region(self._background)
self.line.set_ydata(np.sin(self.i * self.speed + self.x))
self.ax.draw_artist(self.line)
self.i += 1
self.fig.canvas.blit(self.ax.bbox)
def show(self):
plt.show()
AnimatedSinWave().show()
注意:出于各种原因,OSX 和 qt*Agg 后端会发生一些奇怪的事情。如果 window 第一次弹出时背景是黑色的,移动或聚焦 window,它应该会自行修复。
无论如何,如果没有 animated
标志(或较新的动画框架),该示例将变得 多 复杂。