如何在Tkinter窗口指定位置放置Matplotlib绘制的图表?
解决Matplotlib图表在Tkinter中指定位置放置的问题
嘿,作为Python新手遇到这个布局问题太正常啦!你现在用pack()来放置Matplotlib的画布,自然没法自定义位置——要实现精准定位,只需要把pack()换成place()就可以,和你放按钮的思路完全一致。
问题根源
Matplotlib的FigureCanvasTkAgg会生成一个Tkinter兼容的控件,这个控件和普通按钮一样支持Tkinter的三种布局管理器:pack()、grid()、place()。你之前用pack()是让它自动填充顶部区域,但用place()就能精准控制它的位置、大小。
修改后的代码
我帮你调整了plot()方法,还加了个小细节避免多次点击PLOT按钮后图表重叠:
import tkinter as tk from tkinter import ttk, messagebox import serial import serial.tools.list_ports import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import matplotlib.pyplot as plt root = tk.Tk() root.title("ANALYSER") root.geometry("1000x700") root.configure(background='white') def get_ports(): ports = serial.tools.list_ports.comports() return ports def findArduino(portsFound): commPort = 'None' numConnection = len(portsFound) for i in range(numConnection): port = portsFound[i] strPort = str(port) if 'Arduino' in strPort: splitPort = strPort.split(' ') commPort = splitPort[0] return commPort class AppWindow: def __init__(self, window): self.window = window # 按钮用pack没问题,和place布局可以共存 self.connect = ttk.Button(window, text="CONNECT", command=self.Connect) self.connect.pack(pady=10) self.getValue = ttk.Button(window, text="PLOT", command=self.plot) self.getValue.pack(pady=5) # 初始化画布属性,用于后续销毁旧图表 self.canvas_widget = None def Connect(self): self.FoundPorts = get_ports() self.connectPort = findArduino(self.FoundPorts) if self.connectPort != 'None': ser = serial.Serial(self.connectPort, baudrate=9600) print('Connected to ' + self.connectPort) messagebox.showinfo('STATUS', 'CONNECTED') else: print('Connection Issue!') messagebox.showinfo('STATUS', 'NOT CONNECTED!') def plot(self): # 如果之前有画布,先销毁它避免重叠 if self.canvas_widget: self.canvas_widget.destroy() fig = plt.figure(figsize=(8, 4), dpi=100) # 按需调整图表大小 a = fig.add_subplot(111) a.plot([1,1,1,1,2,3,3,4],[8,9,5,6,2,2,2,2]) canvas = FigureCanvasTkAgg(fig, master=self.window) fig.canvas.draw() # 获取Tkinter控件,用place指定位置 self.canvas_widget = canvas.get_tk_widget() # 这里设置x=50, y=100,你可以根据需求修改坐标和尺寸 self.canvas_widget.place(x=50, y=100, width=800, height=400) # 也可以用相对位置,比如relx=0.05, rely=0.2, relwidth=0.9, relheight=0.7(按窗口比例适配) start = AppWindow(root) root.mainloop()
关键修改点
- 新增
self.canvas_widget属性,每次绘图前销毁旧画布,避免多次点击PLOT后图表重叠 - 将
canvas.get_tk_widget().pack(...)替换为place(),并指定了x、y坐标和width、height参数 - 调整了
figsize让图表更适配窗口,你可以根据自己的需求修改这些数值
额外提示
place()的参数非常灵活:
x/y:绝对像素坐标relx/rely:相对窗口的比例(取值0到1之间)width/height:绝对宽度高度relwidth/relheight:相对窗口的宽度高度比例
如果想让按钮也用place()定位,直接把按钮的pack()换成place()就行,比如self.connect.place(x=20, y=20)。
内容的提问来源于stack exchange,提问作者Peouse Dutta
相关产品推荐
相关产品推荐

