Matplotlib 报错导致 tkinter 应用程序崩溃

28

我正在构建一个将matplotlib图形嵌入GUI的应用程序。问题是,只要我在代码中添加来自matplotlib的任何内容(除了导入之外,那些像往常一样工作),我的应用程序就会崩溃。问题出现在我的类Solver_App中的tk.Tk.__init__(self, *args, **kwargs)。运行代码时,我会得到一个庞大的错误,并且应用程序会崩溃。以下是我的一些代码:

import tkinter as tk
from tkinter import ttk

import matplotlib
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure

# Setting up figures for integration in GUI:
fig_3D = plt.figure()
fig_2D = plt.figure()
a_3D = fig_3D.add_subplot(111, projection="3d")
a_2D = fig_2D.add_subplot(111)
a_3D.plot_wireframe([1, 2, 3, 4, 5], [1, 3, 7, 6, 4], [1, 2, 3, 4, 5], color="blue")

class Solver_App(tk.Tk, ttk.Frame):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)  # This is where the app crashes.

        # Equation frame holds everything related to the input and configuration of the equations.
        equation_frame = ttk.Frame(self)
        equation_frame.pack(side="bottom", fill="x", pady=50, padx=50)

        # More code goes here...

# There are more classes with a similar setup as the one above...

app = Solver_App()
app.mainloop()

以下是运行代码时出现的大量错误:

2015-08-14 15:18:29.142 Python[50796:18837594] -[NSApplication _setup:]: unrecognized selector sent to instance 0x10216a830
2015-08-14 15:18:29.143 Python[50796:18837594] An uncaught exception was raised
2015-08-14 15:18:29.143 Python[50796:18837594] -[NSApplication _setup:]: unrecognized selector sent to instance 0x10216a830
2015-08-14 15:18:29.144 Python[50796:18837594] (
    0   CoreFoundation                      0x00007fff9901b03c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff9436476e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff9901e0ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x00007fff98f63e24 ___forwarding___ + 1028
    4   CoreFoundation                      0x00007fff98f63998 _CF_forwarding_prep_0 + 120
    5   Tk                                  0x00000001024ad527 TkpInit + 476
    6   Tk                                  0x0000000102427aca Tk_Init + 1788
    7   _tkinter.so                         0x00000001006e5f2d Tcl_AppInit + 77
    8   _tkinter.so                         0x00000001006e30d6 Tkinter_Create + 934
    9   Python                              0x00000001000e44ce PyEval_EvalFrameEx + 28894
    10  Python                              0x00000001000e5ced PyEval_EvalCodeEx + 2349
    11  Python                              0x000000010003e8ba function_call + 186
    12  Python                              0x000000010000d3c8 PyObject_Call + 104
    13  Python                              0x00000001000e0cb9 PyEval_EvalFrameEx + 14537
    14  Python                              0x00000001000e5ced PyEval_EvalCodeEx + 2349
    15  Python                              0x000000010003e8ba function_call + 186
    16  Python                              0x000000010000d3c8 PyObject_Call + 104
    17  Python                              0x000000010002802c method_call + 140
    18  Python                              0x000000010000d3c8 PyObject_Call + 104
    19  Python                              0x000000010007b831 slot_tp_init + 81
    20  Python                              0x0000000100072d14 type_call + 212
    21  Python                              0x000000010000d3c8 PyObject_Call + 104
    22  Python                              0x00000001000e1b09 PyEval_EvalFrameEx + 18201
    23  Python                              0x00000001000e5ced PyEval_EvalCodeEx + 2349
    24  Python                              0x00000001000e5daf PyEval_EvalCode + 63
    25  Python                              0x000000010011048e PyRun_FileExFlags + 206
    26  Python                              0x000000010011083d PyRun_SimpleFileExFlags + 717
    27  Python                              0x000000010012810e Py_Main + 3262
    28  Python                              0x0000000100000e32 Python + 3634
    29  Python                              0x0000000100000c84 Python + 3204
    30  ???                                 0x0000000000000002 0x0 + 2
)
2015-08-14 15:18:29.144 Python[50796:18837594] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSApplication _setup:]: unrecognized selector sent to instance 0x10216a830'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff9901b03c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff9436476e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff9901e0ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x00007fff98f63e24 ___forwarding___ + 1028
    4   CoreFoundation                      0x00007fff98f63998 _CF_forwarding_prep_0 + 120
    5   Tk                                  0x00000001024ad527 TkpInit + 476
    6   Tk                                  0x0000000102427aca Tk_Init + 1788
    7   _tkinter.so                         0x00000001006e5f2d Tcl_AppInit + 77
    8   _tkinter.so                         0x00000001006e30d6 Tkinter_Create + 934
    9   Python                              0x00000001000e44ce PyEval_EvalFrameEx + 28894
    10  Python                              0x00000001000e5ced PyEval_EvalCodeEx + 2349
    11  Python                              0x000000010003e8ba function_call + 186
    12  Python                              0x000000010000d3c8 PyObject_Call + 104
    13  Python                              0x00000001000e0cb9 PyEval_EvalFrameEx + 14537
    14  Python                              0x00000001000e5ced PyEval_EvalCodeEx + 2349
    15  Python                              0x000000010003e8ba function_call + 186
    16  Python                              0x000000010000d3c8 PyObject_Call + 104
    17  Python                              0x000000010002802c method_call + 140
    18  Python                              0x000000010000d3c8 PyObject_Call + 104
    19  Python                              0x000000010007b831 slot_tp_init + 81
    20  Python                              0x0000000100072d14 type_call + 212
    21  Python                              0x000000010000d3c8 PyObject_Call + 104
    22  Python                              0x00000001000e1b09 PyEval_EvalFrameEx + 18201
    23  Python                              0x00000001000e5ced PyEval_EvalCodeEx + 2349
    24  Python                              0x00000001000e5daf PyEval_EvalCode + 63
    25  Python                              0x000000010011048e PyRun_FileExFlags + 206
    26  Python                              0x000000010011083d PyRun_SimpleFileExFlags + 717
    27  Python                              0x000000010012810e Py_Main + 3262
    28  Python                              0x0000000100000e32 Python + 3634
    29  Python                              0x0000000100000c84 Python + 3204
    30  ???                                 0x0000000000000002 0x0 + 2
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我一直在参考一个教程中的代码,[此处](http://pythonprogramming.net/how-to-embed-matplotlib-graph-tkinter-gui/"如何将Matplotlib图形嵌入到Tkinter GUI中")他们的示例似乎可以正常工作。是什么原因导致了这个问题,怎样才能解决?

  • 我正在使用Python 3.4、matplotlib 1.4.3,运行Mac OS Yosemite。

我觉得你省略了最重要的部分。尝试将其简化为 MCVE,这可能有助于解决问题。当你嵌入 Tkinter 时,一个提示是不要使用 pyplot,而是使用你已经导入的实际的 Figure。你跳过了我们可以看到你是否这样做的地方。 - Ajean
尝试执行以下操作。plt.rcParams['keymap.save'] = '' 这可能是由于Mac的键绑定方式导致的。上次我在Mac上使用tkinter时,如果出现NSException异常,那是因为tkinter和Mac的键绑定方式冲突了。 - Pythonista
7个回答

65

你需要显式地设置TkAgg后端。我能够重现你的错误。使用以下代码,问题得到解决。

import matplotlib
matplotlib.use("TkAgg")  # NOTE: import order matters
from matplotlib import pyplot as plt

请注意,在导入pyplot之后设置TkAgg后端也不起作用;这将导致程序崩溃。您需要在导入pyplot之前设置它。(在MPL 1.4.3,tkinter.TkVersion 8.6下测试)


已为我修复 - 经过mpl 1.5.1和tkinter.TkVersion 8.5测试。 - theicfire
3
为什么这是必要的?为什么这个问题还持续了3年?似乎对于matplotlib内部处理来说,这应该是一个非常简单的修复。 - Janosh
不适用于matplotlib 3.0.3。必须使用qt5而不是tk。 - Bagusflyer
在我的MacBook Pro上,可以使用Python 3.7、matplotlib 3.0.2和tk 8.6.8。非常感谢! - Adrian Keister
尝试过这个,我的Mac崩溃了... "HIToolbox:收到WindowServer事件端口死亡的通知。" MacOS 10.14.6,Python 3.7.3 - RPatel99
在macOS Mojave上,这并不能解决问题。使用另一个后端也不行!它们都会导致macOS的窗口服务器崩溃。 - Konrad Rudolph

0

在导入matplotlib.pyplot之后,设置以下内容:

plt.rcParams['keymap.quit'] = ''

如果绘图被中断,这将避免混乱的产生。 对我来说有效。


0

在导入matplotlib.pyplot之后,设置以下内容:

plt.rcParams['keymap.quit'] = ''

如果绘图被中断,这将避免混乱的产生。但只有在“软”退出时才能实现,即通过代码(键盘/鼠标事件等)。如果通过单击“退出”按钮(“X”)关闭图形(窗口),它并不能解决“混乱”问题。(这仍需解决...我还没有解决!)

示例:

import numpy as np
from matplotlib import pyplot as plt

def keypress(e):
  global animation
  animation = False

plt.connect('key_press_event', keypress)
plt.rcParams['keymap.quit'] = '' # This will avoid mess if plotting is interrupted!

animation = True

delay = 0.5; animation = True
for i in range(1,10):
  if not animation: break
  y = np.random.normal(loc=0.5, scale=0.4, size=1000)
  plt.plot(y)
  plt.pause(delay)

在动画播放期间,按下任意键会平滑地停止它。

0
如果你不想编辑代码,你可以设置以下环境变量,matplotlib会读取它。
MPLBACKEND=TkAgg

无论何时导入pyplot,它都能正常工作。

-1

当我更新到最新的Python环境(3.8.2)后,这个错误消失了,而不需要使用matplotlib.use("TkAgg")。


-1

@DonCristobal的回答对我很有帮助,因此我试图给它点赞或添加评论,但stackoverflow阻止了我这样做,引用了我必须达到某些要求才能发表评论或点赞的某些点。@DonCristobal建议的解决方案适用于我的以下配置:

Mac catalina, python 3.6 & matplotlib 3.0.3

这是我所做的 -

修改了

import matplotlib.pyplot as plt

import matplotlib

matplotlib.use("TkAgg")

from matplotlib import pyplot as plt

-1

我仍然遇到这个问题崩溃:

import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x ** 2)

f = plt.figure()
plt.plot(x, y)
f.show()
plt.pause(0.0001)

窗口出现了一个sin,然后内核就冻结了。 Windows 10与Anaconda3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接