在Tkinter画布小部件类中嵌入matplotlib图 [英] embedding a matplotlib graph in a Tkinter canvas widget class

查看:244
本文介绍了在Tkinter画布小部件类中嵌入matplotlib图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个Tkinter小部件类,该类将matplotlib图形嵌入到画布对象中。我编写的代码几乎可以正常使用,但是在小部件关闭时似乎无法正确退出。这是我正在使用的代码。这不是我正在使用的实际matplotlib图形代码,而是出于问这个问题而写的东西。我原来的matplotlib图形代码很长,太不切实际,无法尝试复制此帖子。

I am trying to create a Tkinter widget class that embeds a matplotlib graph in a canvas object. 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. My original matplotlib graph code is very long and is too impractical to try and copy for this post.

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()

当我运行这段代码时,小部件已正确绘制并表现出预期的效果,但是当我单击关闭图标按钮时,小部件从屏幕上消失,但是代码继续运行,并且空闲提示永远不会再出现,而是空闲提示仅具有闪烁的光标,但是没有提示。通常,当我创建这样的窗口小部件时,当我单击关闭图标按钮时,窗口小部件将关闭,并且基础代码也将退出,从而使我返回到正常的空闲提示。如果有人对如何正确退出此代码有任何想法,我将感谢您的帮助。我假设问题某种程度上与matplotlib嵌入的代码部分有关。真诚的,乔治

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. Sincerely, George

推荐答案

您根本不会使用此代码访问Tkinter,因为您的函数schart2返回,然后将其分配给 self.f 并用于 self.canvas = FigureCanvasTkAgg(self.f)

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).

相反,您获得的窗口来自Matplotlib- plt.plot plt.show 命令会弹出一个纯matplotlib图形。

Rather, the window you're getting is from Matplotlib - the plt.plot and plt.show commands pop up a pure matplotlib figure.

要在Tkinter中获得嵌入式图形,想要的方式,您要做的就是重新执行schart2以返回数字,并且不要使用pyplot:

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:

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

此外:

您还希望删除 self.canvas.show(),因为它会导致以下Tkinter错误一个 update_idletasks属性,但我对Tkinter专家的了解还不够,无法解决这个问题,另外还有一个单独的问题(已经有关于SO的一些讨论)。还有一个名称空间问题-从 side = Tk.TOP,fill = Tk.BOTH 中删除​​ Tk。 ,因为您已经从Tkinter导入* *

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). There is also a namespace issue - take the Tk. off of side=Tk.TOP, fill=Tk.BOTH, because you've done from Tkinter import *.

这篇关于在Tkinter画布小部件类中嵌入matplotlib图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆