简体   繁体   English

在Tkinter画布小部件类中嵌入matplotlib图

[英]embedding a matplotlib graph in a Tkinter canvas widget class

I am trying to create a Tkinter widget class that embeds a matplotlib graph in a canvas object. 我正在尝试创建一个Tkinter小部件类,该类将matplotlib图形嵌入到画布对象中。 The code I have written almost works but doesn't seem to exit properly when the widget is closed. 我编写的代码几乎可以正常工作,但是在关闭小部件时似乎无法正确退出。 Here is the code I am using. 这是我正在使用的代码。 This is not the actual matplotlib graph code I am using but something I wrote for the purpose of asking this question. 这不是我正在使用的实际matplotlib图形代码,而是我为询问此问题而写的东西。 My original matplotlib graph code is very long and is too impractical to try and copy for this post. 我原来的matplotlib图形代码很长,因此无法尝试复制此帖子。

from Tkinter import *
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

def schart2(stock_sym):
    x = [1,2,3,4]
    y = [20,21,20.5, 20.8]
    plt.plot(x,y)
    plt.show()

class StockChart(Frame):
    def __init__(self, stock_sym=''):
        Frame.__init__(self, parent=None)
        self.pack(expand=YES, fill=BOTH)
        self.makeWidgets(stock_sym)

    def makeWidgets(self, stock_sym):
        #self.f = graphData(stock_sym,12,26)
        self.f = schart2(stock_sym)
        self.canvas = FigureCanvasTkAgg(self.f)
        self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        self.canvas.show()



if __name__ == '__main__':
    StockChart('ACAD').mainloop()

When I run this code the widget is properly drawn and behaves as expected, but when I click the close icon button the widget disappears from the screen but the code continues to run and the idle prompt never reappears, instead the idle prompt just has a flashing cursor but no prompt. 当我运行此代码时,窗口小部件已正确绘制并按预期运行,但当我单击关闭图标按钮时,窗口小部件从屏幕上消失了,但代码继续运行,并且不再出现空闲提示,而是空闲提示只是闪烁光标但没有提示。 Normally when I create a widget like this, when I click the close icon button the widget closes and the underlying code also exits returning me to the normal idle prompt. 通常,当我创建这样的窗口小部件时,当我单击关闭图标按钮时,窗口小部件将关闭,并且基础代码也会退出,使我回到正常的空闲提示。 If anyone has any ideas on how to get this code to exit properly I would appreciate the help. 如果有人对如何正确退出此代码有任何想法,我将感谢您的帮助。 I am assuming that the problem is somehow related to the portion of the code which does the matplotlib embedding. 我假设问题某种程度上与matplotlib嵌入的代码部分有关。 Sincerely, George 真诚的乔治

You're not accessing Tkinter at all using this code, because your function schart2 returns None , which is then assigned to self.f and used for self.canvas = FigureCanvasTkAgg(self.f) . 您根本不会使用此代码访问Tkinter,因为您的函数schart2返回None ,然后将其分配给self.f并用于self.canvas = FigureCanvasTkAgg(self.f)

Rather, the window you're getting is from Matplotlib - the plt.plot and plt.show commands pop up a pure matplotlib figure. 而是从Matplotlib获得的窗口plt.plotplt.show命令弹出一个纯matplotlib图形。

To get an embedded figure in Tkinter the way you want, all you have to do is re-do schart2 to return a figure, and don't use pyplot: 要以所需的方式在Tkinter中获得嵌入式图形,您要做的就是重新执行schart2以返回图形,并且不要使用pyplot:

def schart2(stock_sym):
    x = [1,2,3,4]
    y = [20,21,20.5, 20.8]
    fig = Figure()
    axes = fig.add_subplot(111)
    axes.plot(x,y)
    return fig

In addition: 此外:

You'll also want to remove the self.canvas.show() , because it causes a Tkinter error about an 'update_idletasks' attribute, but I'm not enough of a Tkinter expert to figure that one out, plus it's a separate question (there are already a few discussions on SO). 您还需要删除self.canvas.show() ,因为它会导致有关'update_idletasks'属性的Tkinter错误,但是我对Tkinter专家的了解还不够,无法解决这个问题,另外这是一个单独的问题(已经有关于SO的一些讨论)。 There is also a namespace issue - take the Tk. 还有一个名称空间问题-以Tk. off of side=Tk.TOP, fill=Tk.BOTH , because you've done from Tkinter import * . side=Tk.TOP, fill=Tk.BOTH ,因为您已经from Tkinter import *

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM