【发布时间】:2017-10-23 10:00:01
【问题描述】:
注意:这不是关于“动画”图表;而是更新和扩展绘图的数据。
我已经很多看过 PyPlot S.O.关于如何在循环中更新 PyPlot 的问题,但其中许多答案要么已经过时,要么超出了我所寻求的简单性。
我见过的最接近的例子是这样的:
import pylab as pl
from IPython import display
for i in range(10):
pl.plot(pl.randn(100))
display.clear_output(wait=True)
display.display(pl.gcf())
但它会在每次循环迭代时在旧数据之上绘制新数据,完成后会生成两个图表,我只想要一个。
假设我有两行:
l1 = [i for i in range(10)]
l2 = [i^2 for i in range(10)]
我将在每次循环迭代时向每一行添加新数据:
for i in range(11, 20):
l1.append(i)
l2.append(i^2)
我只想看到一个显示更新线条的图。
一些帖子建议使用子图的set_ydata 函数,但这似乎对我不起作用。来自https://stackoverflow.com/a/4098938/5623899的示例
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)
# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma
for phase in np.linspace(0, 10*np.pi, 500):
line1.set_ydata(np.sin(x + phase))
fig.canvas.draw()
只有在整个事情完成后才产生情节。
将该示例更改为我假设的示例失败
l1 = [i for i in range(10)]
l2 = [i^2 for i in range(10)]
print([i^2 for i in range(10)])
print(l2)
import pylab as pl
from IPython import display
fig = plt.figure()
ax = fig.add_subplot(111)
line1 = ax.plot(l1)
line2 = ax.plot(l2)
for i in range(11, 20):
l1.append(i)
l2.append(i^2)
line1.set_ydata(l1)
line2.set_ydata(l2)
fig.canvas.draw()
因为 plt.plot(arr) 中只有一个单一数组导致方法 set_ydata 不存在。
那我该怎么做呢?
【问题讨论】:
-
如果我运行问题中的代码,它只会生成一个图表。所有线条加起来的事实与动画无关,使用
plt.gca().clear()清除每一步中的轴。因此,我同意这是重复的,除非问题使该方法的问题绝对清楚。 -
@ImportanceOfBeingErnest 我并不怀疑您收到的结果。但是,毫无疑问,在我正在运行的 jupyter notebook 中,在循环的最后一次迭代之后,我最终得到了两个图表。使用上面的代码,它将简单地在旧行之上绘制一个新行,更改颜色。这就是问题所在,避免这种情况
-
所以这是两个不同的问题。去除情节中的旧线的解决方案与动画无关,它是添加
plt.gca().clear()。您也可以使用set_ydata来更新情节; “但这似乎不起作用”不是一个充分的问题描述)。可能存在出现两个图的问题,但从问题中并不明显 - 包括正在使用的版本和屏幕截图。 -
@ImportanceOfBeingErnest 我已经按照您的建议添加了更多说明
-
看来你完全无视
plt.gca().clear(),所以这里是第三次了。此外,您的任何尝试实际上都没有使用display,这就是使您的数字显示多次的原因。使用display循环的另一种方法是使用FuncAnimation,其中也有几个答案。
标签: python-3.x matplotlib ipython jupyter-notebook