使用matplotlib运行线程会导致python崩溃

使用matplotlib运行线程会导致python崩溃,python,multithreading,matplotlib,tkinter,Python,Multithreading,Matplotlib,Tkinter,我有一个程序,它有两个非常简单的线程: 一个用于监听串行端口 一个用于文本用户界面 我还有一个matplotlib动画在我的main()中运行。它有一个作用域类,该类是中的示例 当程序开始运行时,它显示绘图,一切正常。问题是,一旦用户输入一个键,程序就会崩溃,python就会退出,并出现致命错误 ui线程与matplotlib和scope类无关。如果我删除创建绘图的代码,则ui线程没有问题,程序运行平稳。我还注意到系统上的matplotlib使用tkinter创建窗口 对于matplotli

我有一个程序,它有两个非常简单的线程:

  • 一个用于监听串行端口
  • 一个用于文本用户界面
我还有一个
matplotlib
动画
在我的
main()
中运行。它有一个
作用域
类,该类是中的示例

当程序开始运行时,它显示绘图,一切正常。问题是,一旦用户输入一个键,程序就会崩溃,python就会退出,并出现致命错误

ui
线程与
matplotlib
scope
类无关。如果我删除创建绘图的代码,则
ui
线程没有问题,程序运行平稳。我还注意到系统上的
matplotlib
使用
tkinter
创建窗口

对于
matplotlib
animation
导致问题的原因,您是否有任何提示或经验?线程不能与
matplotlib
plot
一起使用吗

我在
Windows7
中的命令行窗口中使用
python2.7
运行它

matplotlib
version:2.0.2
Tkinter
版本:8.5

错误:

或此错误:

代码:

第一个错误“致命Python错误:GC对象已被跟踪”于2013年关闭,状态为“closed WONTFIX”,请参见Bugzilla上的

2015年再次提出[与dask有关]时,似乎临时解决方案是使用以下代码:

   import dask
   dask.set_options(get=dask.async.get_sync)
但问题实际上在于
dataframe.read\u csv
问题

问题出在后来的熊猫版本中。如果升级matplotlib版本,问题很可能也会通过类似的修复得到解决


希望这有帮助

如果您提供一个仍然存在此问题的更简单的示例,人们可能更容易调试此问题。看到了吗,当我把这段代码放到python中时,我得到了一个错误:
AttributeError:type对象'listner'没有属性'listner'
,因为这行:
listner\u thread=listner.listner(port)
你确定你提供的代码是在用户点击某个键之前一直工作的代码吗?我更新了代码。这是完全工作和复制的问题。谢谢你的信息。我猜Tkinter有点问题。我在另一台使用
MPL-WebAgg
GUI框架的机器上运行了相同的代码,运行非常顺利。它会在浏览器中打开图形,但这是不可取的。@dandikain在导入pyplot之前插入此行“matplotlib.use('Agg')”,以避免打开窗口-还建议在显示之前保存图表(),例如plt.savefig('fig')尝试了这一点,并将其放在一开始,但它不起作用,并警告说,我应该把它之前调用阴谋!(我是这么做的,我先称它为一切。)根据上面的代码,它应该是第4行,然后导入pyplot。(而不是把线放在一开始)。你试过了吗?@dandikain你能不能调试一下你的代码,然后找到它第一次被导入的地方(很明显,它是在这段代码之前被导入的)。。。然后把线插进去?除此之外,我没有任何建议。希望你能解决这个问题。很高兴部分解决了。
TclStackFree: incorrect freePtr. Call out of sequence?

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
    import threading
import serial
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class listner(threading.Thread):

        def __init__(self,port):
            threading.Thread.__init__(self)
            self.sport=None
            self.is_running=True
            self.init_port(port)

        def run(self):
            print ' Reading from Port'
            while self.is_running:
                try:
                    self.sport.read(1)
                except:
                    print 'Error reading port'

        def init_port(self,port):
            print '1'
            if self.sport==None or not self.sport.is_open :
                try:

                    self.sport = serial.Serial(port,115200)
                    self.sport.timeout = 1
                    self.sport.reset_input_buffer()
                    self.sport.reset_output_buffer()
                    self.port_open=True
                except:
                    print "    Port error Listener Initing\n",self.port_open,'\n',self.sport
            else:
                pass

        def process(self):
            pass


class ui(threading.Thread):

        def __init__(self):
            threading.Thread.__init__(self)     
            self.running = True

        def run(self):

            print 'Starting UI:\n'
            while self.running:
                print ' Enter input ''S'':\n'
                user = raw_input()



def main(port):

        listner_thread = None
        try:
            listner_thread = listner(port)
            listner_thread.start();
        except:
            print "Listener Thread Failed To Start"
            return

        ui_thread=None
        try:
            ui_thread = ui()
            ui_thread.start()          
        except:
            print "UI Thread Failed To Start"
            return

        run_charts()



def run_charts():
        fig, (ax1, ax2) = plt.subplots(2, 1)

        scope1 = Scope(ax1)
        ani1 = animation.FuncAnimation(fig, scope1.update, emit_ch1, interval=10,blit=True)

        scope2 = Scope(ax2)
        ani2 = animation.FuncAnimation(fig, scope2.update, emit_ch2, interval=10,blit=True)

        plt.show()

def emit_ch1():
    yield 0.001

def emit_ch2():
    yield -0.001

class Scope(object):
        def __init__(self, ax, maxt=2, dt=0.02):
            self.ax = ax
            self.dt = dt
            self.maxt = maxt
            self.tdata = [0]
            self.ydata = [0]
            self.line = Line2D(self.tdata, self.ydata)
            self.ax.add_line(self.line)
            self.ax.set_ylim(-.009, 0.009)
            self.ax.set_xlim(0, self.maxt)

        def update(self, y):
            t = self.tdata[-1] + self.dt
            self.tdata.append(t)
            self.ydata.append(y)
            self.line.set_data(self.tdata, self.ydata)
            return self.line,



if __name__ == '__main__':
        main('COM11')
   import dask
   dask.set_options(get=dask.async.get_sync)