Matplotlib图形挂在线程中。使用Thread.join()

时间:2020-03-04 10:03:32

标签: python multithreading matplotlib

考虑以下示例

similar_products

我有一个ILIKE '%\_WIN\_%' ESCAPE '\' 线程执行一个冗长的操作,并且我想监视它的运行时。

因此,我为from time import sleep import matplotlib.pyplot as plt from threading import Thread import numpy as np class Monitor(Thread): def __init__(self): Thread.__init__(self) _, self.ax = plt.subplots() self.data = [] def add_point(self, pt): self.data.append(pt) self.ax.cla() self.ax.plot(self.data) plt.draw() class Main_job(Thread): def __init__(self, monitor): Thread.__init__(self) self.monitor = monitor self.output = [] def run(self): for i in range(20): print(i) pt = np.random.rand() self.output.append(pt) self.monitor.add_point(pt) sleep(1) monitor = Monitor() monitor.start() main = Main_job(monitor) main.start() 图定义了Main_job,为我的过程定义了另一个。

代码运行正常

现在让我们说,在关闭程序之前,我想对Thread线程的输出进行某些操作(例如,将其打印或保存到文件中)。

我在代码末尾添加了以下几行

matplotlib

但是,这以某种方式干扰了Main_job,尽管根本没有修改main.join() print(main.output) 线程,但现在挂起直到matplotlib完成。

如何等待monitor完成,但同时又避免main挂起?

编辑1-单线程(无效)版本

在FiddleStix请求之后,这是代码的单线程版本。尽管简单得多,但在此版本中,该图仍然挂起并且仅在过程结束时显示

main

在绘制后添加monitor可以稍微改善这种情况。但是,通过这种方式可以显示图形,但是用户只能在0.01s内进行交互。

注意:我知道可以用from time import sleep import matplotlib.pyplot as plt import numpy as np _, ax = plt.subplots() output = [] for i in range(20): print(i) pt = np.random.rand() output.append(pt) ax.cla() ax.plot(output) sleep(1) 替换plt.pause(0.01)来解决问题,但是这里sleep(1)只是长时间执行真实代码中的操作的代理,而不是只是一个停顿。

2 个答案:

答案 0 :(得分:0)

我认为您想使Monitor线程成为daemon线程(docs)。如果主线程停止,则守护程序线程将自动退出。这样,您可以在后台运行某些程序,而无需显式停止第二个线程。

您只需添加类参数即可将线程声明为守护程序:

class Monitor(Thread):
    daemon = True

答案 1 :(得分:0)

GUI mainloop应该在主线程中运行。在一个单独的线程中运行您的作业,以免阻塞GUI。

通过在线程中使用matplotlib.pyplot.draw执行重绘,可以实现随着output的变化而绘制的简单动画。

请考虑使用Animation API来平滑地绘制实时图。

from time import sleep
import matplotlib.pyplot as plt
from threading import Thread
import numpy as np


_, ax = plt.subplots()

output = []

class Job(Thread):
    def run(self):
        for i in range(10):
            print(i)
            pt = np.random.rand()
            output.append(pt)
            sleep(1)
            ax.cla()
            ax.plot(output)
            plt.draw()

job = Job()
job.start()

plt.show()
相关问题