我编写应用程序会显示动态变化的数据(从套接字读取的数据)。
作为一个虚拟案例,我尝试绘制一个幅度乘以每秒1.1的正弦值:
import numpy as np
import matplotlib.pyplot as plt
import time
x = np.arange(0, 10, 0.1);
y = np.sin(x)
for i in xrange(100):
plt.plot(x, y)
time.sleep(1)
y=y*1.1
这显然不是这样做的,但它表明了我的意图。
如何正确完成?
修改 以下是@mskimm答案中建议的代码的回溯输出:
plt.show() #Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "<ipython-input-5-ed773f8e3e84>", line 7, in update
plt.draw()
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 466, in draw
get_current_fig_manager().canvas.draw()
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 240, in draw
tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/tkagg.py", line 12, in blit
tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
RuntimeError: main thread is not in main loop
编辑2:
事实证明,在qtconsole中运行相同的代码...(任何想法为什么?)
然而,每次打印重新缩放到情节,所以&#34;动画效果&#34;不见了。
我尝试使用plt.autoscale_view(False,False,False)
,但这根本没有引起任何情节。
答案 0 :(得分:10)
有更好的方法可以使用matplotlib animation API执行此操作, 但这是一个快速而肮脏的方法:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 10, 0.1)
y = np.sin(x)
plt.ion()
ax = plt.gca()
ax.set_autoscale_on(True)
line, = ax.plot(x, y)
for i in xrange(100):
line.set_ydata(y)
ax.relim()
ax.autoscale_view(True,True,True)
plt.draw()
y=y*1.1
plt.pause(0.1)
关键步骤是:
plt.ion()
启用互动模式。plot
。plt.pause
。我包含了自动缩放视口的代码,但这并不是绝对必要的。
答案 1 :(得分:2)
申请animated
难吗?如何使用thread
更新图形。
即使plt.show()
阻止,thread
也会更新数字。
import numpy as np
import matplotlib.pyplot as plt
import time
import threading
def update(x, y):
for i in xrange(100):
# clear
plt.clf()
plt.plot(x, y)
# draw figure
plt.draw()
time.sleep(1)
y=y*1.1
x = np.arange(0, 10, 0.1);
y = np.sin(x)
plt.plot(x, y)
# use thread
t = threading.Thread(target=update, args=(x, y))
t.start()
plt.show() # blocking but thread will update figure.
答案 2 :(得分:0)
另一种解决方案是从头开始重新绘制图。当然,它比逐点更新要慢,但是如果您没有很多点,则开销可以忽略不计。
from IPython import display
def dynamic_plot(X,Y, figsize=[10,5], max_x=None, min_y=None, max_y=None):
'''plots dependency between X and Y dynamically: after each call current graph is redrawn'''
gcf().set_size_inches(figsize)
cla()
plot(X,Y)
if max_x:
plt.gca().set_xlim(right=max_x)
if min_y:
plt.gca().set_ylim(bottom=min_y)
if max_y:
plt.gca().set_ylim(top=max_y)
display.display(gcf())
display.clear_output(wait=True)
以及jupyter笔记本的演示用途:
import time
X=[]
Y=[]
for i in range(10):
X.append(i)
Y.append(i**.5)
dynamic_plot(X,Y,[14,10], max_x=10, max_y=4)
time.sleep(0.3)