我有问题,试图使matplotlib绘图函数没有阻塞执行。
我已经尝试使用show(block=False)作为一些人的建议,但我得到的只是一个冻结的窗口。如果我简单地调用show(),结果会被正确地绘制,但执行会被阻塞,直到窗口关闭。从我读过的其他线程来看,我怀疑show(block=False)是否有效取决于后端。这对吗?我的后台是Qt4Agg。你能不能看一下我的代码,如果有什么问题请告诉我?这是我的代码。
from math import *
from matplotlib import pyplot as plt
print(plt.get_backend())
def main():
x = range(-50, 51, 1)
for pow in range(1,5): # plot x^1, x^2, ..., x^4
y = [Xi**pow for Xi in x]
print(y)
plt.plot(x, y)
plt.draw()
#plt.show() #this plots correctly, but blocks execution.
plt.show(block=False) #this creates an empty frozen window.
_ = raw_input("Press [enter] to continue.")
if __name__ == '__main__':
main()
PS.我忘了说,我想更新现有的窗口,每次我绘制一些东西,而不是创建一个新的。
Iggy的答案对我来说是最容易理解的,但当我做一个后续的subplot命令时,我得到了以下错误,当时我只是在做show:
MatplotlibDeprecationWarning:使用相同的参数添加轴
作为前一个轴当前重用较早的实例。在未来
版本时,总会创建并返回一个新实例。
同时,此警告可以被抑制,并对未来的行为进行抑制
通过向每个axis实例传递唯一的标签来确保。
为了避免这种错误,它有助于关闭(或清除)绘图后,用户按下回车键。
下面是对我有用的代码:
def plt_show():
'''Text-blocking version of plt.show()
Use this instead of plt.show()'''
plt.draw()
plt.pause(0.001)
input("Press enter to continue...")
plt.close()
我发现plt.pause(0.001)命令是唯一需要的东西,其他什么都不需要。
Plt.show()和plt.draw()是不必要的和/或以某种方式阻塞。这是一个绘制和更新图形的代码。本质上,plt.pause(0.001)似乎最接近matlab的drawnow。
不幸的是,除非您插入input()命令,否则这些图将不是交互式的(它们会冻结),但随后代码将停止。
pl .pause(interval)命令的文档说明:
如果有活动图形,它将在暂停......之前更新并显示
这可以用于粗糙的动画。
这就是我们想要的。试试下面的代码:
import numpy as np
from matplotlib import pyplot as plt
x = np.arange(0, 51) # x coordinates
for z in range(10, 50):
y = np.power(x, z/10) # y coordinates of plot for animation
plt.cla() # delete previous plot
plt.axis([-50, 50, 0, 10000]) # set axis limits, to avoid rescaling
plt.plot(x, y) # generate new plot
plt.pause(0.1) # pause 0.1 sec, to force a plot redraw
您可以通过将绘图写入数组,然后在不同的线程中显示该数组来避免阻塞执行。下面是一个使用pyformulas 0.2.8中的pf.screen同时生成和显示绘图的示例:
import pyformulas as pf
import matplotlib.pyplot as plt
import numpy as np
import time
fig = plt.figure()
canvas = np.zeros((480,640))
screen = pf.screen(canvas, 'Sinusoid')
start = time.time()
while True:
now = time.time() - start
x = np.linspace(now-2, now, 100)
y = np.sin(2*np.pi*x) + np.sin(3*np.pi*x)
plt.xlim(now-2,now+1)
plt.ylim(-3,3)
plt.plot(x, y, c='black')
# If we haven't already shown or saved the plot, then we need to draw the figure first...
fig.canvas.draw()
image = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
image = image.reshape(fig.canvas.get_width_height()[::-1] + (3,))
screen.update(image)
#screen.close()
结果:
免责声明:我是pyformulas的维护者。
Matplotlib:将图保存到numpy数组