我有问题,试图使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.我忘了说,我想更新现有的窗口,每次我绘制一些东西,而不是创建一个新的。


当前回答

很多答案都被夸大了,据我所知,答案并不难理解。

如果您愿意,可以使用plt.ion(),但我发现使用plt.draw()同样有效

对于我的特定项目,我正在绘制图像,但你可以使用plot()或scatter()或其他东西来代替figimage(),这没有关系。

plt.figimage(image_to_show)
plt.draw()
plt.pause(0.001)

Or

fig = plt.figure()
...
fig.figimage(image_to_show)
fig.canvas.draw()
plt.pause(0.001)

如果你用的是实际数字。 我使用@krs013和@默认图片的答案来计算这个 希望这能让人们不必在单独的线程上发布每个人物,或者不必为了弄清楚这个问题而阅读这些小说

其他回答

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()

替换matplotlib后端可以解决我的问题。 在导入matplotlib之前,编写下面的命令。Pyplot = plt。 替换后端命令应该首先运行。

进口matplotlib matplotlib用(TkAgg’)。

我的答案来自Pycharm,不显示情节

很多答案都被夸大了,据我所知,答案并不难理解。

如果您愿意,可以使用plt.ion(),但我发现使用plt.draw()同样有效

对于我的特定项目,我正在绘制图像,但你可以使用plot()或scatter()或其他东西来代替figimage(),这没有关系。

plt.figimage(image_to_show)
plt.draw()
plt.pause(0.001)

Or

fig = plt.figure()
...
fig.figimage(image_to_show)
fig.canvas.draw()
plt.pause(0.001)

如果你用的是实际数字。 我使用@krs013和@默认图片的答案来计算这个 希望这能让人们不必在单独的线程上发布每个人物,或者不必为了弄清楚这个问题而阅读这些小说

Python包drawnow允许以非阻塞的方式实时更新绘图。 它还与网络摄像头和OpenCV一起工作,例如绘制每一帧的测量值。 请看原文。

生活策划

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
# plt.axis([x[0], x[-1], -1, 1])      # disable autoscaling
for point in x:
    plt.plot(point, np.sin(2 * point), '.', color='b')
    plt.draw()
    plt.pause(0.01)
# plt.clf()                           # clear the current figure

如果数据量太多,你可以用一个简单的计数器降低更新速率

cnt += 1
if (cnt == 10):       # update plot each 10 points
    plt.draw()
    plt.pause(0.01)
    cnt = 0

程序退出后按住Plot

这是我无法找到满意答案的实际问题,我想要在脚本完成后不关闭的绘图(如MATLAB),

如果你仔细想想,在剧本完成后,程序就终止了,没有任何逻辑上的方式来维持情节,所以有两种选择

阻止脚本退出(这是plt.show(),而不是我想要的) 在单独的线程上运行情节(太复杂了)

这对我来说并不满意,所以我在盒子外面找到了另一个解决方案

外部查看器中的SaveToFile和View

为此,保存和查看都应该是快速的,查看器不应该锁定文件,应该自动更新内容

选择保存格式

基于矢量的格式既小又快

SVG很好,但除了默认需要手动刷新的web浏览器之外,它找不到好的查看器 PDF可以支持矢量格式,还有支持实时更新的轻量级查看器

快速轻量级查看器与实时更新

对于PDF,有几个不错的选项

在Windows上,我使用SumatraPDF,它是免费的,快速的,轻便的(我只使用1.8MB RAM) 在Linux上有几个选项,如Evince (GNOME)和Ocular (KDE)

示例代码和结果

将图形输出到文件的示例代码

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(2 * x)
plt.plot(x, y)
plt.savefig("fig.pdf")

在第一次运行之后,在上面提到的一个查看器中打开输出文件,然后欣赏。

下面是一个VSCode和SumatraPDF的截图,这个过程也足够快,可以获得半实时更新速率(我可以在我的设置中接近10Hz,只需要在间隔之间使用time.sleep())