embedding a matplotlib graph in a Tkinter canvas widget class

大憨熊 提交于 2019-12-25 01:42:08

问题


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

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


回答1:


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

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

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

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



来源:https://stackoverflow.com/questions/27546777/embedding-a-matplotlib-graph-in-a-tkinter-canvas-widget-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!