如何让Matplotlib图表随Tkinter主窗口大小自适应?
让Matplotlib图表随Tkinter主窗口自适应缩放的解决方案
要让你的Matplotlib图表随主窗口调整大小自动缩放,需要补充以下几处代码逻辑:
关键修改点
- 配置Tkinter网格布局权重,让承载图表的
Notebook组件能随窗口拉伸 - 给图表画布绑定尺寸变化事件,监听窗口缩放动作
- 实现自适应回调函数,根据新画布尺寸调整图表大小并重新绘制
修改后的完整代码
import tkinter as tk from tkinter import ttk import os import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import pandas as pd class AppWindow(tk.Tk): def __init__(self): super().__init__() self.notebook = None self.df = None self.df_1 = None self.build_app_window() def build_app_window(self): self.title("env_viewer") btn_refresh = tk.Button(self, text="Aktualisieren", command=self.refresh) btn_refresh.grid(row=3, column=0, sticky="new", padx=5) # 配置主窗口网格权重,让Notebook所在区域随窗口拉伸 self.grid_columnconfigure(1, weight=1) self.grid_rowconfigure(2, weight=1) self.notebook = ttk.Notebook(self) self.notebook.grid(row=2, column=1, rowspan=10, sticky="nsew") self.add_voltage_tab() def add_voltage_tab(self): # 创建Figure,无需固定尺寸,后续自适应调整 self.fig_voltage, self.ax_voltage = plt.subplots(dpi=100) # 生成Matplotlib画布 self.canvas_voltage = FigureCanvasTkAgg(self.fig_voltage, master=self.notebook) canvas_widget = self.canvas_voltage.get_tk_widget() # 设置画布填充父容器并允许扩展 canvas_widget.pack(fill=tk.BOTH, expand=True) # 绑定画布尺寸变化事件到缩放回调 canvas_widget.bind('<Configure>', self.on_voltage_canvas_resize) self.notebook.add(canvas_widget, text='Spannung') def on_voltage_canvas_resize(self, event): # 通过DPI转换,将画布像素尺寸转为Figure英寸尺寸 new_width = event.width / self.fig_voltage.dpi new_height = event.height / self.fig_voltage.dpi # 更新Figure尺寸 self.fig_voltage.set_size_inches(new_width, new_height) # 仅当数据已加载时重绘图表 if self.df is not None: self.update_voltage_plot() def update_voltage_plot(self): dates = self.df['Date Time'] voltage = self.df['Voltage[V]'] self.ax_voltage.clear() self.ax_voltage.plot(dates, voltage, color="blue", label="Spannung [V]") self.ax_voltage.legend(loc='upper left') self.fig_voltage.autofmt_xdate(rotation=45) self.fig_voltage.tight_layout() self.canvas_voltage.draw() def refresh(self): dir_path = os.path.dirname(os.path.realpath(__file__)) self.filepath_1 = os.path.join(dir_path, "2023-07_environment_data.csv") self.df_1 = pd.read_csv(str(self.filepath_1), sep=';') self.update_df() self.update_voltage_plot() def update_df(self): self.df = self.df_1 self.df['Date Time'] = pd.to_datetime(self.df['Date Time']) self.df = self.df.sort_values(by='Date Time') if __name__ == "__main__": MainWindow = AppWindow() MainWindow.mainloop()
补充说明
- 网格权重设置确保
Notebook能占据主窗口的可用空间,随窗口大小变化自动拉伸 <Configure>事件会在画布尺寸改变时触发回调,通过DPI转换避免图表缩放后模糊- 增加
self.df is not None判断,防止窗口初始化阶段还未加载数据就触发重绘报错
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

