Python gui中的Matplotlib崩溃

Python gui中的Matplotlib崩溃,python,matplotlib,crash,tkinter,imshow,Python,Matplotlib,Crash,Tkinter,Imshow,我想用imshow和tkinter在gui中绘制一个矩阵。问题是,在进一步更新之后,gui崩溃。我无法在网上找到答案。你能帮我吗 守则: from numpy import * from Tkinter import * import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg from matplotlib.fi

我想用imshow和tkinter在gui中绘制一个矩阵。问题是,在进一步更新之后,gui崩溃。我无法在网上找到答案。你能帮我吗

守则:

from numpy import *
from Tkinter import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure

root = Tk()
f1 = Figure()

canvas = FigureCanvasTkAgg(f1, master=root)
canvas.show()
canvas.get_tk_widget().pack(fill="x")
a = f1.add_subplot(111)
a.get_axes().set_frame_on(True)
ini = [[i] * 100 for i in range(100)]
cax = a.matshow(ini)

while True:
    mat = random.randint(0, 2**16-1, (1000, 1000))
    cax.set_data(mat)
    canvas.draw()

root.mainloop()

感谢您的建议fhdrsdg,但这样做会在执行重画时冻结窗口,这很无聊,尤其是在前面有很多事情要做的时候

这是我的密码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from Tkinter import Button, Label, Text, Checkbutton, Radiobutton, Frame, Tk, Entry, INSERT, StringVar, IntVar, Toplevel, END
from ttk import Notebook, Combobox
from numpy import arange, zeros, array, uint16, empty, divide, random, ravel
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from matplotlib import cm
from matplotlib.image import AxesImage
import time
from threading import Thread
import os



class Image_direct(Thread):

    def __init__(self):
        Thread.__init__(self)
        self.encore = True

    def run(self):
        """This loop can be long ~10s"""
        while self.encore:
            time.sleep(1)
            app.cax.set_extent((0, 1023, 1023, 0))
            mat = random.randint(0, 2**16-1, (1024, 1024)).astype("uint16")
            app.update_camera(mat)

    def stop(self):
        self.encore = False


class Deu(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.creer_applets()

    def creer_applets(self):
        self.fen4 = Frame(fen)
        self.fen4.pack(side="bottom", fill="both")
        self.fen1 = Frame(fen, width=200)
        self.fen1.pack(side="left", fill="both", expand=False)
        self.note = Notebook(fen, width=1)
        self.tab_mat = Frame(self.note)
        self.note.add(self.tab_mat, text = "Caméra", compound="top")
        self.note.pack(side="left", fill="both", expand=True)
        self.fen3 = Frame(fen, width=250)
        self.fen3.pack(side="left", fill="both", expand=False)

        Button(self.fen4, text="Quit", command=self.aurevoir).pack(fill="x", side="top")

        self.interp = StringVar()
        self.interp.set("none")
        liste_interp = ["none", "nearest", "bilinear", "bicubic", "spline16", "spline36", "hanning", "hamming", "hermite", "kaiser", "quadric", "catrom", "gaussian", "bessel", "mitchell", "sinc", "lanczos"]
        self.choix_interp = Combobox(self.tab_mat, textvariable=self.interp, state="readonly", width=10)
        self.choix_interp['values'] = liste_interp
        self.cmap = StringVar()
        self.cmap.set("jet")
        palettes = sorted(m for m in cm.datad if not m.endswith("_r"))
        self.choix_palette = Combobox(self.tab_mat, textvariable=self.cmap, state="readonly", width=10)
        self.choix_palette['values'] = palettes
        self.bouton_palette = Button(self.tab_mat, text="Changer la palette", command=self.changer_cmap)

        self.f1 = Figure()
        self.canvas1 = FigureCanvasTkAgg(self.f1, master=self.tab_mat)
        self.canvas1.show()
        self.canvas1.get_tk_widget().pack(fill="both", expand=1)
        NavigationToolbar2TkAgg(self.canvas1, self.tab_mat)
        self.a = self.f1.add_subplot(111)
        self.bg = self.canvas1.copy_from_bbox(self.a.bbox)
        self.a.get_axes().set_frame_on(True)
        ini = random.randint(0, 2**16-1, (1024, 1024))
        self.cax = self.a.matshow(ini, cmap=self.cmap.get(), interpolation=self.interp.get(), picker=True, alpha=1.0)
        self.a.format_coord = lambda x, y: 'x=%d, y=%d, z=%d' % (x, y, ini[round(y), round(x)])
        self.cbar = self.f1.colorbar(self.cax)
        self.cbar.set_label("coups")
        self.bouton_palette.pack(side="left")
        self.choix_interp.pack(side="left")
        self.choix_palette.pack(side="left")

        Button(self.tab_mat, text=">", command=lambda: self.changer_cbar(1)).pack(side="right")
        self.cbar_auto = IntVar()
        self.chb3 = Checkbutton(self.tab_mat, text="Auto?", variable=self.cbar_auto, onvalue=1, offvalue=0, indicatoron=0, command=lambda: self.changer_cbar(0))
        self.chb3.select()
        self.chb3.pack(side="right")
        Button(self.tab_mat, text="<", command=lambda: self.changer_cbar(-1)).pack(side="right")

        self.bouton_direct_on = Button(self.fen3, width=20, text="Démarrer le direct", command=self.image_direct_on)
        self.bouton_direct_on.place(x=0, y=400)
        self.bouton_direct_off = Button(self.fen3, width=20, text="Arrêter le direct", command=self.image_direct_off)
        self.bouton_direct_off.config(state="disabled")
        self.bouton_direct_off.place(x=0, y=430)

    def changer_cbar(self, sens):
        if sens == -1:
            self.cbar.set_clim(vmin=self.cax.get_array().min(), vmax=0.9*self.cbar.get_clim()[1])
        elif sens == 0 and self.cbar_auto.get():
            self.cbar.set_clim(vmin=self.cax.get_array().min(), vmax=self.cax.get_array().max())
        elif sens == 1:
            self.cbar.set_clim(vmin=self.cax.get_array().min(), vmax=2*self.cbar.get_clim()[1])
        self.cax.set_clim(self.cbar.get_clim())
        self.canvas1.restore_region(self.bg)
        self.a.draw_artist(self.f1)
        self.canvas1.blit(self.f1.bbox)

    def changer_cmap(self):
        self.cax.set_cmap(self.cmap.get())
        self.cax.set_interpolation(self.interp.get())
        self.canvas1.draw()

    def update_camera(self, mat):
        xmin = min([int(i) for i in app.a.get_xlim()])
        xmax = max([int(i) for i in app.a.get_xlim()])
        ymin = min([int(i) for i in app.a.get_ylim()])
        ymax = max([int(i) for i in app.a.get_ylim()])
        self.a.format_coord = lambda x, y: 'x=%d, y=%d, z=%d' % (x, y, mat[round(y), round(x)])
        self.cax.set_data(mat)
        self.changer_cbar(0)

    def image_direct_on(self):
        self.bouton_direct_off.config(state="normal")
        self.bouton_direct_on.config(state="disabled")
        self.dire = Image_direct()
        self.dire.setDaemon(True)
        self.dire.start()

    def image_direct_off(self):
        self.bouton_direct_off.config(state="disabled")
        self.bouton_direct_on.config(state="normal")
        self.dire.stop()
        del self.dire

    def aurevoir(self):
        try:
            self.dire.isAlive()
        except:
            pass
        else:
            self.dire.stop()
        fen.quit()
        fen.destroy()


if __name__ == '__main__':
    fen = Tk()
    fen.geometry("1300x750")
    app = Deu(fen)
    fen.mainloop()
#/usr/bin/env python
#-*-编码:utf-8-*-
从Tkinter导入按钮、标签、文本、复选按钮、Radiobutton、框架、Tk、条目、插入、StringVar、IntVar、Toplevel、END
从ttk导入笔记本,组合框
从numpy导入arange、零、数组、uint16、空、除、随机、ravel
导入matplotlib
matplotlib.use('TkAgg')
从matplotlib.backends.backend_tkagg导入图CAVASTKAGG,导航工具栏2TKAGG
从matplotlib.figure导入图形
从matplotlib导入cm
从matplotlib.image导入AxesImage
导入时间
从线程导入线程
导入操作系统
类图像\u直接(线程):
定义初始化(自):
线程。\uuuu初始化\uuuuu(自)
self.encore=True
def运行(自):
“”“此循环可以长约10秒”“”
而self.encore:
时间。睡眠(1)
应用程序cax.set_范围((0,1023,1023,0))
mat=random.randint(0,2**16-1,(10241024)).astype(“uint16”)
应用程序更新\u摄像头(mat)
def停止(自):
self.encore=False
类Deu(框架):
定义初始(自我,主):
帧。\uuuu初始化(自,主)
self.creer_applets()
def creer_小程序(自):
self.fen4=帧(fen)
self.fen4.pack(side=“bottom”,fill=“bottom”)
self.fen1=框架(fen,宽度=200)
self.fen1.pack(side=“left”,fill=“both”,expand=False)
self.note=笔记本(分,宽度=1)
self.tab_mat=框架(self.note)
self.note.add(self.tab_mat,text=“Caméra”,component=“top”)
self.note.pack(side=“left”,fill=“both”,expand=True)
self.fen3=框架(fen,宽度=250)
self.fen3.pack(side=“left”,fill=“both”,expand=False)
按钮(self.fen4,text=“Quit”,command=self.aurevoir).pack(fill=“x”,side=“top”)
self.interp=StringVar()
自我解释集(“无”)
liste_interp=[“无”、“最近”、“双线性”、“双三次”、“样条16”、“样条36”、“汉宁”、“汉明”、“埃尔米特”、“凯撒”、“二次”、“catrom”、“高斯”、“贝塞尔”、“米切尔”、“辛克”、“兰佐斯”]
self.choix\u interp=组合框(self.tab\u mat,textvariable=self.interp,state=“readonly”,width=10)
self.choix_interp['values']=liste_interp
self.cmap=StringVar()
self.cmap.set(“jet”)
选项板=已排序(如果不是m.endswith(“\r”),则m代表cm.datad中的m)
self.choix\u调色板=组合框(self.tab\u mat,textvariable=self.cmap,state=“readonly”,width=10)
self.choix_调色板['values']=调色板
self.bouton\u调色板=按钮(self.tab\u mat,text=“Changer la palete”,command=self.Changer\u cmap)
self.f1=图()
self.canvas1=图CAVASTKAGG(self.f1,master=self.tab\u mat)
self.canvas1.show()
self.canvas1.get_tk_widget().pack(fill=“both”,expand=1)
导航工具栏2TKAGG(self.canvas1,self.tab_mat)
self.a=self.f1.添加_子批次(111)
self.bg=self.canvas1.copy_from_bbox(self.a.bbox)
self.a.get_axes().set_frame_on(真)
ini=random.randint(0,2**16-1,(10241024))
self.cax=self.a.matshow(ini,cmap=self.cmap.get(),interpolation=self.interp.get(),picker=True,alpha=1.0)
self.a.format_-coord=lambda x,y:'x=%d,y=%d,z=%d%%(x,y,ini[round(y),round(x)])
self.cbar=self.f1.colorbar(self.cax)
self.cbar.set_标签(“政变”)
self.bouton_调色板包(side=“left”)
自选择内包装(侧=“左”)
self.choix_调色板包(side=“left”)
按钮(self.tab_mat,text=“>”,command=lambda:self.changer_cbar(1)).pack(side=“right”)
self.cbar_auto=IntVar()
self.chb3=检查按钮(self.tab\u mat,text=“Auto?”,变量=self.cbar\u Auto,onvalue=1,offvalue=0,指示符号=0,命令=lambda:self.changer\u cbar(0))
self.chb3.select()
自助式chb3.pack(side=“right”)

按钮(self.tab_mat,text=“我认为问题在于运行
while True
循环。 尝试使用
after
方法限制每次重复之间的时间。 下面的代码每100ms更新一次画布

from numpy import *
from Tkinter import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure

root = Tk()
f1 = Figure()

canvas = FigureCanvasTkAgg(f1, master=root)
canvas.show()
canvas.get_tk_widget().pack(fill="x")
a = f1.add_subplot(111)
a.get_axes().set_frame_on(True)
ini = [[i] * 100 for i in range(100)]
cax = a.matshow(ini)

def redraw():
    mat = random.randint(0, 2**16-1, (1000, 1000))
    cax.set_data(mat)
    canvas.draw()
    root.after(100, redraw)

redraw()
root.mainloop()

您得到了什么错误使问题复杂化的是没有错误消息。这似乎是内存泄漏或缓存内存溢出…我使用python 2.7.8,matplotlib 1.3.1。使用win7 64位和非官方Windows 64位二进制文件执行python扩展包: