matplotlib.pyplot/pylab在isinteractive()时不更新图形,使用ipython -pylab
关于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 个回答
我在我的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
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()
。
你链接的那个问题的第二个回答给出了答案:在每次调用 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()
这个函数是关键部分。