为什么Matplotlib图形在关闭后会卡住?

qvsjd97n  于 2023-01-02  发布在  其他
关注(0)|答案(1)|浏览(188)

请考虑这段启动两个线程的代码,每个线程都执行python代码:创建一个图,一些标注和显示图形。这些代码是在主线程中执行的Matplotlib要求。

import queue
import threading

def runScriptMainThread(code):
    print(threading.current_thread())
    print("Code : ", code)
    exec(code)

def runScript(code):
    callback_queue.put(lambda: runScriptMainThread(code))

callback_queue = queue.Queue()
threading.Thread(target=runScript, args=("import matplotlib.pyplot as plt;plt.plot([1, 2, 3, 4]);plt.ylabel('some numbers');plt.show(block=True);",)).start()
threading.Thread(target=runScript, args=("import matplotlib.pyplot as plt;plt.plot([5, 6, 3, 4]);plt.ylabel('some numbers');plt.show(block=True);",)).start()

while True:
    try:
        callback = callback_queue.get(block=False)
        callback()
        print("After callback")
    except queue.Empty:  # raised when queue is empty
        print("Empty")

执行此代码将生成以下输出:

<_MainThread(MainThread, started 4525688320)>
Code :  import matplotlib.pyplot as plt;plt.plot([1, 2, 3, 4]);plt.ylabel('some numbers');plt.show(block=True);
After callback
<_MainThread(MainThread, started 4525688320)>
Code :  import matplotlib.pyplot as plt;plt.plot([5, 6, 3, 4]);plt.ylabel('some numbers');plt.show(block=True);
After callback
Empty
Empty
...

执行第一个线程的第一个代码,当matplotlib图形关闭时,执行第二个线程的第二个代码,并显示第二个图形。但当第二个图形关闭时,其窗口被卡住,始终可见:它不会消失。
您知道如何正确关闭最后一个窗口吗?
MacOSX 12.6操作系统
Python 3.9
图库3.4.1
PyCharm CE 2022.1(构建编号PC-221.5080.212,构建日期:2022年4月12日)
PS:我正在使用py4j从Java运行python代码,这就是我处理多线程的原因。

5uzkadbs

5uzkadbs1#

既然你在主线程上运行所有的matplotlib代码,我猜这个问题与线程代码无关,我建议你试试这个简化的脚本,看看它的行为是否与你的相同。

import matplotlib.pyplot as plt

def plot_numbers(numbers):
    plt.plot(numbers)
    plt.ylabel('some numbers')
    plt.show(block=True)

plot_numbers([1, 2, 3, 4])
plot_numbers([5, 6, 3, 4])
while True:
    print('Empty')

如果它的行为相同,那么我怀疑您遇到了matplotlib的MacOS后端之一的问题。尝试切换到不同的后端,如this post中所述。
仅供参考,当我尝试在Ubuntu 20.04上使用Python 3.9和matplotlib 3.6.0运行您的代码或我的简化代码时,我没有发现问题。

相关问题