【问题标题】:Python: matplotlib - loop, clear and show different plots over the same figurePython:matplotlib - 循环、清除并在同一图形上显示不同的图
【发布时间】:2017-07-18 04:31:24
【问题描述】:

我想使用循环查看绘图如何随着不同值的变化而变化。我想在同一个情节上看到它。但我不想保留图中之前的情节。在 MATLAB 中,这可以通过创建一个图形并在同一个图形上绘图来实现。循环结束时关闭它。

喜欢,

fh = figure();
%for loop here
%do something with x and y    
subplot(211), plot(x);
subplot(212), plot(y); 
pause(1)
%loop done
close(fh);

我无法在 matplotlib 中找到与此等效的内容。通常所有的问题都与在同一个情节上绘制不同的系列有关,这在 matplotlib 上似乎很自然,通过使用plt.plot() 绘制几个系列,然后最后使用plt.show() 显示它们。但我想刷新剧情。

【问题讨论】:

标签: python matlab matplotlib plot


【解决方案1】:

在 matplotlib 中创建动画基本上有两种不同的方法

交互模式

使用plt.ion() 来开启交互式更多功能。即使show 尚未被调用,这也会创建一个绘图。可以通过调用plt.draw() 来更新情节,或者对于动画,plt.pause()

import matplotlib.pyplot as plt

x = [1,1]
y = [1,2]

fig, (ax1,ax2) = plt.subplots(nrows=2, sharex=True, sharey=True)
line1, = ax1.plot(x)
line2, = ax2.plot(y)
ax1.set_xlim(-1,17)
ax1.set_ylim(-400,3000)
plt.ion()

for i in range(15):
    x.append(x[-1]+x[-2])
    line1.set_data(range(len(x)), x)
    y.append(y[-1]+y[-2])
    line2.set_data(range(len(y)), y)

    plt.pause(0.1)

plt.ioff()    
plt.show()

FuncAnimation

Matplotlib 提供了一个animation submodule,它简化了动画的创建并允许轻松保存它们。与上面相同,使用FuncAnimation 看起来像:

import matplotlib.pyplot as plt
import matplotlib.animation

x = [1,1]
y = [1,2]

fig, (ax1,ax2) = plt.subplots(nrows=2, sharex=True, sharey=True)
line1, = ax1.plot(x)
line2, = ax2.plot(y)
ax1.set_xlim(-1,18)
ax1.set_ylim(-400,3000)


def update(i):
    x.append(x[-1]+x[-2])
    line1.set_data(range(len(x)), x)
    y.append(y[-1]+y[-2])
    line2.set_data(range(len(y)), y)

ani = matplotlib.animation.FuncAnimation(fig, update, frames=14, repeat=False)   
plt.show()

一个用不断变化的频率和功率谱制作正弦波动画的例子如下:

import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np

x = np.linspace(0,24*np.pi,512)
y = np.sin(x)

def fft(x):
    fft = np.abs(np.fft.rfft(x))
    return fft**2/(fft**2).max()

fig, (ax1,ax2) = plt.subplots(nrows=2)
line1, = ax1.plot(x,y)
line2, = ax2.plot(fft(y))
ax2.set_xlim(0,50)
ax2.set_ylim(0,1)

def update(i):
    y = np.sin((i+1)/30.*x)
    line1.set_data(x,y)
    y2 = fft(y)
    line2.set_data(range(len(y2)), y2)

ani = matplotlib.animation.FuncAnimation(fig, update, frames=60, repeat=True)  
plt.show()

【讨论】:

  • 是的,这很好。但我需要为每个循环绘制 cleared 的情节。我不需要看到旧点。在您的情况下,您正在更新一行,因为它的增长,如果对于 for 循环中的每个值,有一个完全不同的行。 ?我想看见这个。例如,我生成一个正弦波,并且每次在循环中改变它的频率,我想看到峰值在频域中移动的趋势。类似的东西。
  • 您可能误解了这些示例。他们更新线路数据。所以没有显示旧点。如果从一个步骤到下一个步骤的数据完全改变,则更新的行将同样完全改变,始终显示为其设置的实际数据。
  • 我更新了答案,举例说明了我认为您在询问“趋势峰值移动”时正在寻找的内容。
  • 嘿。惊人的。谢谢你。我知道了。是的,我误解了。对于那个很抱歉。是的,更新线路数据,这就是我现在所做的并且我能够做到。在此之前我不知道以下类型:。我正在逐行浏览您的示例。好的。再次感谢。
  • 感谢更新的答案。我还没有尝试动画方法。我很快就会通过它们。看起来真的很有趣。现在,我用第一种方法本身得到了我需要的东西。类似于 MATLAB 的东西。我也“接受”了你的回答。
【解决方案2】:

如果您在循环内调用plt.show(),只要您关闭包含该图形的窗口,您就会看到循环中每个元素的绘图。该过程将针对第一个元素进行绘图,然后如果您关闭窗口,您将看到循环中第二个元素的绘图,等等

【讨论】:

  • 是的,我希望这会自动发生,使用暂停命令。我不想手动关闭它。如果清除相同的图形并且可以在其中绘制新图像,那将是理想的。
  • 一个简单的方法是在下一个绘图之前添加一个延迟,使用 time.sleep,然后在绘制下一个之前关闭旧绘图。
猜你喜欢
  • 2020-10-14
  • 2022-12-10
  • 2021-02-28
  • 2013-11-25
  • 2014-06-16
  • 2021-11-25
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
相关资源
最近更新 更多