matplotlib 图在 tkinter 中改变大小 window
matplotlib plot changes size in tkinter window
在此示例中,您可以输入点坐标,然后将其保存在树视图中并绘制。很简单。不过我发现我可以 "initialize" 我的情节按照我想要的方式格式化,但是一旦我添加第一点,情节似乎 "grow" 并占用更多的 tkinter window。我不知道为什么会发生这种情况或如何控制它以保持其原始大小。谢谢
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()
我真的不能说为什么地块面积增加了。不过,我可以告诉你的是,你使用了错误的策略。每次添加一个新点时,您都在创建一个新图形和新 canvas,这会浪费大量能量并导致您遇到问题。相反,您应该创建一个空图,其中包含一个空艺术家,并在每次单击该按钮时向该艺术家添加新点。
看代码(我做的修改主要在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()
在此示例中,您可以输入点坐标,然后将其保存在树视图中并绘制。很简单。不过我发现我可以 "initialize" 我的情节按照我想要的方式格式化,但是一旦我添加第一点,情节似乎 "grow" 并占用更多的 tkinter window。我不知道为什么会发生这种情况或如何控制它以保持其原始大小。谢谢
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()
我真的不能说为什么地块面积增加了。不过,我可以告诉你的是,你使用了错误的策略。每次添加一个新点时,您都在创建一个新图形和新 canvas,这会浪费大量能量并导致您遇到问题。相反,您应该创建一个空图,其中包含一个空艺术家,并在每次单击该按钮时向该艺术家添加新点。
看代码(我做的修改主要在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()