matplotlib图在tkinter窗口中更改大小

时间:2018-11-29 12:41:33

标签: python matplotlib tkinter-canvas

在此示例中,您可以输入点坐标,然后将其保存在树形视图中并进行绘制。很简单。不过,我发现我可以“初始化”我的绘图以按照自己的意愿进行格式化,但是一旦我添加了第一个点,绘图就似乎在“增长”并占用了更多的tkinter窗口。我不知道为什么会发生这种情况或如何控制这种情况,以使其保持其原始大小。谢谢。

import tkinter as tk
from tkinter import ttk
import numpy as np

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


class MainGUI(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title('Title')
        self.geometry('750x500')

        self.nb = ttk.Notebook(self)
        self.nb.grid(row=0, column=0, columnspan=5, rowspan=4, sticky='NESW')
        self.tab2 = ttk.Frame(self.nb)
        self.nb.add(self.tab2, text='Tab2')

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        tab2_r = 8
        tab2_c = 4
        for i in range(tab2_r):
            self.tab2.rowconfigure(i, weight=1)
        for i in range(tab2_c):
            self.tab2.columnconfigure(i, weight=1)

        self.makeTable()
        self.makePlot()
        self.makeWidgets()

    def makeWidgets(self):
        self.Labels = []
        self.Entries = []
        self.labText = [('X Location:'), ('Y Location:')]

        self.xGrid = 1
        self.yGrid = int(np.ceil(len(self.labText) / self.xGrid))
        i = 0
        for j in range(0, self.xGrid + 1, 2):
            for k in range(self.yGrid):
                if(i == len(self.labText)):
                    break
                else:
                    self.label = tk.Label(self.tab2, text=self.labText[i])
                    self.label.grid(column=j, row=k + 8, sticky='SW')
                    self.Labels.append(self.label)
                    self.entry = tk.Entry(self.tab2)
                    self.entry.insert(0, '0.0000')
                    self.entry.grid(column=j + 1, row=k + 8, sticky='NS')
                    self.Entries.append(self.entry)
                    i += 1

        self.addBtn = tk.Button(self.tab2, text='Add Entry', command=self.addEntry)
        self.addBtn.grid(column=self.xGrid + 1, row=self.yGrid + 9, sticky='NSEW')

    def makeTable(self):
        tab_header = ['Pattern #', 'Description']
        self.tree = ttk.Treeview(self.tab2, columns=tab_header, height=5, show="headings")
        vsb = ttk.Scrollbar(self.tab2, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=vsb.set)
        self.tree.grid(column=0, row=0, columnspan=2, rowspan=5, sticky='NSEW')
        vsb.grid(column=1, row=0, rowspan=5, sticky='ENS')
        self.tree.heading(tab_header[0], text=tab_header[0].title())
        self.tree.column(tab_header[0], width=30, anchor='center')
        self.tree.heading(tab_header[1], text=tab_header[1].title())
        self.tree.column(tab_header[1], width=170, anchor='center')
        self.tree.insert('', 'end', values=("", "(new)"))
        self.counter = 1

    def addEntry(self):
        check = (len(self.tree.get_children()) == 1)
        self.description = "Location: " + self.Entries[0].get() + ", " + self.Entries[1].get()
        self.tree.insert('', 'end', values=(self.counter, self.description))
        newEntry = [float(self.Entries[0].get()), float(self.Entries[1].get())]
        if(check == True):
            self.points = newEntry
        else:
            self.points = np.vstack((self.points, newEntry))
        self.counter += 1
        self.plotstuff()

    def makePlot(self):
        self.fig = Figure(figsize=(1, 1), dpi=100)
        self.ptrnFig = self.fig.add_subplot(111)
        self.ptrnFig.plot([1], [1])
        self.ptrnFig.axis([-1, 1, -1, 1])
        self.ptrnFig.spines['left'].set_position('zero')
        self.ptrnFig.spines['bottom'].set_position('zero')
        self.ptrnFig.grid(True)
        self.canvas = FigureCanvasTkAgg(self.fig, self.tab2)
        self.canvas.draw()
        self.canvas.get_tk_widget().grid(column=2, row=0, columnspan=2, rowspan=5, sticky='NSEW')

    def plotstuff(self):
        self.ptrnFig.cla()
        if(np.ndim(self.points) == 1):
            x = self.points[0]
            y = self.points[1]
        else:
            x = self.points[:, 0]
            y = self.points[:, 1]
        self.ptrnFig.grid(True)
        self.ptrnFig.axis('equal')
        self.ptrnFig.scatter(x, y, c="b", marker="o")
        self.canvas = FigureCanvasTkAgg(self.fig, self.tab2)
        self.canvas.draw()
        self.canvas.get_tk_widget().grid(column=2, row=0, columnspan=2, rowspan=5, sticky='NSEW')


def main():
    MainGUI().mainloop()


if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:1)

我真的不能说为什么情节的面积在增加。不过,我可以告诉您的是您使用了错误的策略。每当您添加新点时,您就在创建新图形和新画布,这浪费了大量精力并给您带来了麻烦。相反,您应该创建一个具有空艺术家的空情节,并在每次单击该按钮时向该艺术家添加新点。

考虑代码(我所做的修改大部分在makePlot()plotstuff()中):

import tkinter as tk
from tkinter import ttk
import numpy as np

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


class MainGUI(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.title('Title')
        self.geometry('750x500')

        self.nb = ttk.Notebook(self)
        self.nb.grid(row=0, column=0, columnspan=5, rowspan=4, sticky='NESW')
        self.tab2 = ttk.Frame(self.nb)
        self.nb.add(self.tab2, text='Tab2')

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        tab2_r = 8
        tab2_c = 4
        for i in range(tab2_r):
            self.tab2.rowconfigure(i, weight=1)
        for i in range(tab2_c):
            self.tab2.columnconfigure(i, weight=1)

        self.makeTable()
        self.makePlot()
        self.makeWidgets()

    def makeWidgets(self):
        self.Labels = []
        self.Entries = []
        self.labText = [('X Location:'), ('Y Location:')]

        self.xGrid = 1
        self.yGrid = int(np.ceil(len(self.labText) / self.xGrid))
        i = 0
        for j in range(0, self.xGrid + 1, 2):
            for k in range(self.yGrid):
                if(i == len(self.labText)):
                    break
                else:
                    self.label = tk.Label(self.tab2, text=self.labText[i])
                    self.label.grid(column=j, row=k + 8, sticky='SW')
                    self.Labels.append(self.label)
                    self.entry = tk.Entry(self.tab2)
                    self.entry.insert(0, '0.0000')
                    self.entry.grid(column=j + 1, row=k + 8, sticky='NS')
                    self.Entries.append(self.entry)
                    i += 1

        self.addBtn = tk.Button(self.tab2, text='Add Entry', command=self.addEntry)
        self.addBtn.grid(column=self.xGrid + 1, row=self.yGrid + 9, sticky='NSEW')

    def makeTable(self):
        tab_header = ['Pattern #', 'Description']
        self.tree = ttk.Treeview(self.tab2, columns=tab_header, height=5, show="headings")
        vsb = ttk.Scrollbar(self.tab2, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=vsb.set)
        self.tree.grid(column=0, row=0, columnspan=2, rowspan=5, sticky='NSEW')
        vsb.grid(column=1, row=0, rowspan=5, sticky='ENS')
        self.tree.heading(tab_header[0], text=tab_header[0].title())
        self.tree.column(tab_header[0], width=30, anchor='center')
        self.tree.heading(tab_header[1], text=tab_header[1].title())
        self.tree.column(tab_header[1], width=170, anchor='center')
        self.tree.insert('', 'end', values=("", "(new)"))
        self.counter = 1

    def addEntry(self):
        check = (len(self.tree.get_children()) == 1)
        self.description = "Location: " + self.Entries[0].get() + ", " + self.Entries[1].get()
        self.tree.insert('', 'end', values=(self.counter, self.description))
        newEntry = [float(self.Entries[0].get()), float(self.Entries[1].get())]
        if(check == True):
            self.points = np.array(newEntry, ndmin=2)
        else:
            self.points = np.vstack((self.points, newEntry))
        self.counter += 1
        self.plotstuff()

    def makePlot(self):
        self.fig = Figure(figsize=(1, 1), dpi=100)
        self.ptrnFig = self.fig.add_subplot(111)
        self.ptrnFig.axis([-1, 1, -1, 1])
        self.ptrnFig.spines['left'].set_position('zero')
        self.ptrnFig.spines['bottom'].set_position('zero')
        self.ptrnFig.grid(True)
        self.canvas = FigureCanvasTkAgg(self.fig, self.tab2)
        self.canvas.draw()
        self.canvas.get_tk_widget().grid(column=2, row=0, columnspan=2, rowspan=5, sticky='NSEW')
        self.scat = self.ptrnFig.scatter([], [], c="b", marker="o")

    def plotstuff(self):
        self.scat.set_offsets(self.points)
        # adjust the limits of the axes
        xmin = min(self.points[:, 0])
        xmax = max(self.points[:, 0])
        ymin = min(self.points[:, 1])
        ymax = max(self.points[:, 1])
        self.ptrnFig.set_xlim(xmin - 0.1 * (xmax - xmin), xmax + 0.1 * (xmax - xmin))
        self.ptrnFig.set_ylim(ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin))
        self.canvas.draw_idle()


def main():
    MainGUI().mainloop()


if __name__ == '__main__':
    main()