tkinter 嵌入到 Matplotlib

tkinter 嵌入到 Matplotlib#

matplotlib.colorsmatplotlib.markers 记录了 Matplotlib 的图像的颜色与形状的样式表单。

将 tkinter 嵌入到 Matplotlib 是很简单的。首先载入一些必备包:

from tkinter import *
from tkinter.ttk import *
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

接着使用 Matplotlib 的 Figure 创建画布,并画一些点:

figure = Figure(figsize=(5, 4), dpi=100)
plot = figure.add_subplot(1, 1, 1)
plot.plot(0.5, 0.3, color="#C41E3A", marker="o", linestyle="")

x = [ 0.1, 0.2, 0.3 ]
y = [ -0.1, -0.2, -0.3 ]
plot.plot(x, y, color="blue", marker="x", linestyle="")

最后,将 tkinter 嵌入:

root = Tk()
canvas = FigureCanvasTkAgg(figure, root)
canvas.get_tk_widget().grid(row=0, column=0)
root.mainloop()

效果图如下:

下面是一个完整的例子:

from tkinter import Tk, ttk

# 创建画布需要的库
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# 创建工具栏需要的库
from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk
# Implement the default Matplotlib key bindings. 快捷键需要的模块
from matplotlib.backend_bases import key_press_handler
# 导入绘图需要的模块
from matplotlib.figure import Figure
import numpy as np

def create_figure():
    # 画布的大小和分别率
    fig = Figure(figsize=(5, 4), dpi=100)
    t = np.arange(0, 3, .01)
    # 利用子图画
    fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
    # 创建画布控件
    return fig

# 绑定快捷键函数
def on_key_press(event):
    print("you pressed {}".format(event.key))
    key_press_handler(event, canvas, toolbar)
    
# 退出函数
def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate

root = Tk()
root.wm_title("Embedding in Tk")
fig = create_figure()
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
# 创建工具条控件
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
# 显示工具条控件
canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
# 调用快捷键函数
canvas.mpl_connect("key_press_event", on_key_press)
# 退出按钮控件
button = ttk.Button(master=root, text="Quit", command=_quit)
button.pack(side='bottom')
# 消息循环
root.mainloop()
# If you put root.destroy() here, it will cause an error if the window is
# closed with the window manager.

复杂点的:

import matplotlib
matplotlib.use('TkAgg')

import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure

from tkinter import Tk, ttk

class Application(Tk):
    '''
    文件夹选择程序
        界面与逻辑分离
    '''
    def __init__(self):
        '''初始化'''
        super().__init__()
        self.wm_title("Embed matplotlib in tkinter")
        self.createWidgets()

    def create_figure_canvas(self, figure):
        self.canvas = FigureCanvasTkAgg(figure, master=self)
        tkcanvas = self.canvas.get_tk_widget()
        tkcanvas.create_rectangle([20, 20, 200, 200], fill='red')
        toolbar = NavigationToolbar2Tk(self.canvas, self)
        toolbar.update()
        footframe = ttk.Frame(master=self)
        footframe.pack(side='bottom')
        tkcanvas.pack(side='top', fill='both', expand=1)
        ttk.Button(master=footframe, text='重画', command=self.draw).pack(side='left')
        ttk.Button(master=footframe, text='退出', command=self._quit).pack(side='left')
        self.draw() # 绘图

    def createWidgets(self):
        '''界面'''
        fig = Figure(figsize=(10, 10),dpi=80,facecolor="pink",edgecolor='green',frameon=True)
        self.ax = fig.add_subplot(111)
        self.create_figure_canvas(fig)

        
    def draw(self):
        '''绘图逻辑'''
        x = np.random.randint(0,50,size=100)
        y = np.random.randint(0,50,size=100)
        self.ax.clear()
        self.ax.scatter(x, y, s=3)  # 重新画
        self.canvas.draw()
    
    
    def _quit(self):
        '''退出'''
        self.quit()     # 停止 mainloop
        self.destroy()  # 销毁所有部件

        
if __name__ == '__main__':
    # 实例化Application
    app = Application()  
    # 主消息循环:
    app.mainloop()