当前位置: 首页 > 知识库问答 >
问题:

使用Matplotlib以非阻塞方式绘图

贲俊才
2023-03-14

在过去的几天里,我一直在玩Numpy和matplotlib。我有问题试图使matplotlib图函数不阻塞执行。我知道已经有很多线程在SO上问类似的问题,我已经谷歌了很多,但还没有成功。

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

共有3个答案

乜烨霖
2023-03-14

您可以通过将图写入数组,然后在不同的线程中显示数组来避免阻塞执行。下面是一个同时生成和显示绘图的示例,使用的是py公式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()

结果:

免责声明:我是py公式的维护者。

参考:Matplotlib:保存情节到Numpy数组

许典
2023-03-14

对我有效的一个简单技巧是:

  1. 在show中使用block=False参数:plt.show(block=False)
  2. 在. py脚本的末尾使用另一个plt.show()。

例子:

import matplotlib.pyplot as plt

plt.imshow(add_something)
plt.xlabel("x")
plt.ylabel("y")

plt.show(block=False)

#more code here (e.g. do calculations and use print to see them on the screen

plt.show()

注:plt。show()是我脚本的最后一行。

宗政金鹏
2023-03-14

我花了很长时间寻找解决方案,并找到了这个答案。

看起来,为了得到你(和我)想要的东西,你需要结合plt。ion()plt。show()。暂停(.001)(或您想要的任何时间)。需要暂停,因为GUI事件发生在主代码(包括绘图)Hibernate时。这可能是通过从睡眠线程中提取时间来实现的,所以可能IDE会弄糟这一点——我不知道。

下面是一个在python 3.5上适用于我的实现:

import numpy as np
from matplotlib import pyplot as plt

def main():
    plt.axis([-50,50,0,10000])
    plt.ion()
    plt.show()

    x = np.arange(-50, 51)
    for pow in range(1,5):   # plot x^1, x^2, ..., x^4
        y = [Xi**pow for Xi in x]
        plt.plot(x, y)
        plt.draw()
        plt.pause(0.001)
        input("Press [enter] to continue.")

if __name__ == '__main__':
    main()
 类似资料:
  • 问题内容: 最近几天,我一直在与Numpy和matplotlib一起玩。我在尝试使matplotlib绘制函数而不阻止执行时遇到问题。我知道这里已经有很多线程在问类似的问题,并且我已经在Google上搜索了很多,但是没有设法使这项工作有效。 我曾尝试按照某些人的建议使用show(block = False),但是我得到的只是一个冻结的窗口。如果我简单地调用show(),则将正确绘制结果,但执行将被

  • 问题内容: 我想使用redis的pubsub传输一些消息,但不想使用阻止,例如以下代码: 最后一部分将被阻止。我只想检查给定频道中是否有数据,该如何完成?有没有类似的方法? 问题答案: 我认为那不可能。通道没有任何“当前数据”,您订阅了一个通道并开始接收该通道上其他客户端推送的消息,因此它是一个阻塞的API。另外,如果您查看pub / sub 的Redis Commands文档,将会更加清楚。

  • 我完全混淆了,,。 哪个是阻塞,哪个不是? 我的意思是如果我使用父进程是否等待子进程返回/才继续执行。 如何影响这些调用?

  • 非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 ServletInputStream.setReadListener 或ServletOutputStream.setWriteListener 方法时将抛出IllegalStateException。为了支持在 Ser

  • Web 容器中的非阻塞请求处理有助于提高对改善 Web 容器可扩展性不断增加的需求,增加 Web 容器可同时处理请求的连接数量。servlet 容器的非阻塞 IO 允许开发人员在数据可用时读取数据或在数据可写时写数据。非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 S

  • 我正在使用Spring WebFlux WebClient从外部API检索数据,如下所示: 这很好,并产生如下响应: 但我只对“temp”属性感兴趣(主要- 我知道第一件事是用“.exchange()”替换“.retrieve()”,但我不知道如何使它工作。 PS:这是我的第一个问题。如果我做错了什么,或者你需要更多细节,请告诉我。 谢啦!