matplotlib.pyplot/pylab在isinteractive()时不更新图形,使用ipython -pylab

16 投票
4 回答
31628 浏览
提问于 2025-04-15 21:23

关于matplotlib、pylab、pyplot和ipython的问题有很多,如果你已经厌烦看到这些问题,我感到抱歉。我会尽量具体一些,因为我查看了很多人的问题和pyplot与pylab的文档,但我仍然不确定自己哪里出错了。接下来是我的代码:

目标:每0.5秒绘制一个图形,并在调用绘图命令时立即更新图形。

我尝试的代码如下(在ipython -pylab环境下运行):


import time
ion()
x=linspace(-1,1,51)
plot(sin(x))
for i in range(10):
    plot([sin(i+j) for j in x])
    #see **
    print i
    time.sleep(1)
print 'Done'

代码能正确绘制每一条线,但只有在退出循环后才会显示。我尝试在**的位置强制重绘,使用draw(),但似乎也没有效果。理想情况下,我希望能简单地添加每一条线,而不是完全重绘。不过,如果必须重绘,那也没问题。

我尝试解决的其他方法:
ion()之后,尝试添加hold(True),但没有效果。
为了好玩,尝试在**的位置使用show()
我找到的最接近我想做的答案是在不阻塞执行绘制线条,但show()没有任何作用。

如果这是一个简单的请求,而我却忽略了什么明显的东西,我感到抱歉。值得一提的是,这个问题是在我尝试将matlab代码转换为一些python代码以供自己使用时出现的。以下是我一直在尝试转换的原始matlab代码(初始化部分已去除):


for i=1:time
    plot(u)
    hold on
    pause(.01)
    for j=2:n-1
        v(j)=u(j)-2*u(j-1)
    end
    v(1)= pi
    u=v
end

任何帮助都非常好,即使只是“查找这个方法”,这样我至少可以缩小范围,弄清楚如何使用那个方法。如果还有其他有用的信息,请告诉我。

4 个回答

5

我在我的Mac上也遇到了完全一样的问题。(我用的是Enthought的Python 2.7 32位版本,运行在Snow Leopard的Macbook Pro上。)

我从工作中的朋友那里得到了一个建议。可以在终端里用以下参数运行ipython:

ipython -wthread -pylab

这样做对我有效。之前“Daniel G”提供的那段Python代码运行时没有问题,而之前它无法更新图表。

根据ipython的说明:

[-gthread, -qthread, -q4thread, -wthread, -pylab:...] 这些参数为GTK、Qt(3和4版本)以及WXPython工具包和matplotlib库提供了线程支持。

我不知道这为什么重要,但确实有效。

希望这对你有帮助,
labjunky

9
from pylab import *
import time
ion()
tstart = time.time()               # for profiling
x = arange(0,2*pi,0.01)            # x-array
line, = plot(x,sin(x))
for i in arange(1,200):
    line.set_ydata(sin(x+i/10.0))  # update the data
    draw()                         # redraw the canvas
    pause(0.01)
print 'FPS:' , 200/(time.time()-tstart)
ioff()
show()

########################
上面的代码对我来说运行得很好。我是在win7操作系统下的pythonxy2.7.3的spyder编辑器中运行的。
注意在draw()之后有一个pause()语句,接着是ioff()show()

9

你链接的那个问题的第二个回答给出了答案:在每次调用 plot() 之后,记得调用 draw(),这样图形就会立刻显示出来;比如:

import time
ion()
x = linspace(-1,1,51)
plot(sin(x))
for i in range(10):
    plot([sin(i+j) for j in x])
    # make it appear immediately
    draw()
    time.sleep(1)

如果这样还不行……可以试试这个页面上的方法: http://www.scipy.org/Cookbook/Matplotlib/Animations

import time

ion()

tstart = time.time()               # for profiling
x = arange(0,2*pi,0.01)            # x-array
line, = plot(x,sin(x))
for i in arange(1,200):
    line.set_ydata(sin(x+i/10.0))  # update the data
    draw()                         # redraw the canvas

print 'FPS:' , 200/(time.time()-tstart)

这个页面提到 line.set_ydata() 这个函数是关键部分。

撰写回答