【问题标题】:Matplotlib animation in Jupyter notebook creates additional empty plotJupyter notebook 中的 Matplotlib 动画创建了额外的空图
【发布时间】:2018-04-18 16:18:45
【问题描述】:

我已经开始为 DSP 讲座创建一系列交互式笔记本。到目前为止,我已经成功复制并实现了下面粘贴的 MWE。然而,除了包含动画的 matplotlib 图,我总是得到一个空的 Matplotlib 窗口。任何想法如何抑制这种行为?

蟒蛇:3.6.3 matplotlib:2.0 和 2.1 IPython:5.3.0 操作系统:Win 7 64 位

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

from matplotlib import animation
from IPython.display import HTML

plt.rcParams['figure.figsize'] = (5,3)
plt.rcParams['figure.dpi'] = 100
plt.rcParams['savefig.dpi'] = 100
plt.rcParams["animation.html"] = "jshtml"  # for matplotlib 2.1 and above, uses JavaScript
#plt.rcParams["animation.html"] = "html5" # for matplotlib 2.0 and below, converts to x264 using ffmpeg video codec
t = np.linspace(0,2*np.pi)
x = np.sin(t)

fig, ax = plt.subplots()
ax.axis([0,2*np.pi,-1,1])
l, = ax.plot([],[])

def animate(i):
    l.set_data(t[:i], x[:i])

ani = animation.FuncAnimation(fig, animate, frames=len(t))
ani

笔记本也可以在下面查看:

https://github.com/chipmuenk/dsp_fpga/blob/master/notebooks/01_LTI/MWE_animation.ipynb

在 github 的静态渲染中,只显示空的绘图窗口,不显示 JavaScript 动画。

【问题讨论】:

  • 移除魔法%matplotlib inline 或改用%matplotlib agg
  • 我尝试了不同的后端,但问题是笔记本将在虚拟服务器上运行,学生将登录该虚拟服务器并与他们的浏览器进行交互。对我来说,将输出限制在一个窗口中似乎是最干净的解决方案。
  • 两种解决方法都会在浏览器中呈现所有内容,但没有空图。

标签: python animation matplotlib plot jupyter


【解决方案1】:

您可以在最后一行之前添加plt.close()

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

from matplotlib import animation
from IPython.display import HTML

plt.rcParams['figure.figsize'] = (5,3)
plt.rcParams['figure.dpi'] = 100
plt.rcParams['savefig.dpi'] = 100
plt.rcParams["animation.html"] = "jshtml"  # for matplotlib 2.1 and above, uses JavaScript
#plt.rcParams["animation.html"] = "html5" # for matplotlib 2.0 and below, converts to x264 using ffmpeg video codec
t = np.linspace(0,2*np.pi)
x = np.sin(t)

fig, ax = plt.subplots()
ax.axis([0,2*np.pi,-1,1])
l, = ax.plot([],[])

def animate(i):
    l.set_data(t[:i], x[:i])

ani = animation.FuncAnimation(fig, animate, frames=len(t))
plt.close()
ani

【讨论】:

  • 这是为我做的!谢谢。
【解决方案2】:

这是一个替代示例:

%matplotlib inline
from matplotlib import animation, pyplot as plt
import numpy as np
plt.rc('animation', html='html5')

data = np.random.random(20)
fig = plt.figure()

ax = fig.add_subplot(111)   
ax.plot(data) # draw background

anim = animation.ArtistAnimation(fig, [[ax.scatter(x, y)] for x, y in enumerate(data)])
anim

结果 (anim) 以动画形式显示,但潜在的副作用是静态帧的附加显示。如果 plt.figure 调用发生在 add_subplot 方法之前的单独单元格中,则此副作用消失。

这是有效的,因为(就像 ImportanceOfBeingErnest 所说的那样)新图形的创建会导致显示静态图像的副作用(描述在笔记本中当前单元格评估结束时图形是如何留下的)。但是,如果还没有在图形上填充任何内容(甚至没有轴),您将阻止显示任何图像(不需要 jupyter 魔法来抑制它)。

【讨论】:

  • 另一种选择是完全省略%matplotlib inline,或者如果这不可行,则在创建用于动画的图形之后立即重复它。这重置了显示静态图形的魔力,这些静态图形不属于单元格结果的一部分;动画本身是通过完全不同的机制显示的(涉及单元格评估结果的 html 格式)。
【解决方案3】:

这与动画无关。

线条

%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots()

将创建一个带有空图的输出。

您可以使用 %%capture 阻止 jupyter notebook 中单元格的输出。

单元格1:

%%capture
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.animation
plt.rcParams["animation.html"] = "jshtml"
import numpy as np

t = np.linspace(0,2*np.pi)
x = np.sin(t)

fig, ax = plt.subplots()
h = ax.axis([0,2*np.pi,-1,1])
l, = ax.plot([],[])

def animate(i):
    l.set_data(t[:i], x[:i])

ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))

单元格2:

ani

【讨论】:

  • 整洁!在浏览 %%capture 时,我找到了另一个解决方案: fig, ax = plt.subplots() plt.close();也为我做了伎俩。 figax 的句柄显然不会通过关闭绘图来删除。是否有理由偏爱其中一种解决方案?
  • 不,这两种解决方案起作用的原因实际上是一样的:情节是封闭的。通过移动到下一个单元格或在单元格内关闭它。选择您更喜欢的方法。
  • 只是控制按钮!
  • 当我把它放到一个函数中时,这只会绘制 x 值
  • 我发现使用plt.close() after 创建动画 (ani = ...) 的行对于防止动画空白很重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
  • 2018-01-25
  • 2019-02-04
  • 2017-09-06
  • 2013-10-03
相关资源
最近更新 更多