You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tkinter中实现滚动条内多图表垂直堆叠展示?

在Tkinter中垂直堆叠带滚动条的Matplotlib图表,或无滚动条放置多图表的方案

一、解决滚动条中垂直堆叠图表的问题

你的代码存在两个关键问题导致图表无法垂直堆叠:

  1. 图表部件的布局方向错误:build_graph中使用side=tk.LEFT会让图表横向排列,需改为垂直方向布局。
  2. 新增图表后未更新滚动区域:每次添加新图表后,Canvas的滚动范围不会自动更新,需手动触发。

修改后的完整代码如下,关键改动已标注:

# importing tkinter gui
import tkinter as tk
from tkinter import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# import functions

def build_graph(root):
    figure3 = plt.Figure(figsize=(5, 4), dpi=100)
    ax3 = figure3.add_subplot(111)
    x = [i for i in range(100)]
    points = [i for i in range(100)]
    ax3.plot(x, points, color='b')
    scatter3 = FigureCanvasTkAgg(figure3, root)
    # 改动1:改为垂直堆叠布局,fill=tk.X适配容器宽度,pady增加间距
    scatter3.get_tk_widget().pack(side=tk.TOP, fill=tk.X, pady=5)
    ax3.legend(['average voltage difference'])
    ax3.set_xlabel('measurement points')
    ax3.set_ylabel('voltage(V)')
    ax3.set_title('Chart')
    # 改动2:更新Canvas滚动区域,确保滚动条识别新增内容
    root.update_idletasks()
    my_canvas.config(scrollregion=my_canvas.bbox(ALL))

# creating window
window = tk.Tk()

# getting screen width and height of display
width = window.winfo_screenwidth()
height = window.winfo_screenheight()

# setting tkinter window size
window.geometry("%dx%d" % (width, height))
window.title("Interface")
label = tk.Label(window, bg='lightblue', text="charts") # creating a label
label.pack() # showing label

# Create A Main frame
top_frame = Frame(master=window) # making an empty container for properties, buttons and fields
top_frame.pack(fill=BOTH,expand=1, side=TOP) # what is fill, expand, side?

# Create Frame for X Scrollbar
top_frame_first = LabelFrame(top_frame, text="Properties")
top_frame_first.pack(fill=X,side=TOP)

# making a new field
frames_number_label = Label(top_frame_first, bg='lightblue', text="enter frames quantity")
frames_number_label.pack(side = LEFT)
frames_number_box = Entry(top_frame_first, width=5)
frames_number_box.insert(0, "1")
frames_number_box.pack(side = LEFT)

path_label = Label(top_frame_first, bg='lightblue', text="write path to file")
path_label.pack(side=LEFT)
path_box = Entry(top_frame_first)
path_box.insert(0, 'experimental.txt')
path_box.pack(side=LEFT)

# Create A Main frame
main_frame = Frame(window)
main_frame.pack(fill=BOTH,expand=1)

# Create Frame for X Scrollbar
sec = Frame(main_frame)
sec.pack(fill=X,side=BOTTOM)

# Create A Canvas
my_canvas = Canvas(main_frame)
my_canvas.pack(side=LEFT,fill=BOTH,expand=1)

# # Add A Scrollbars to Canvas
y_scrollbar = Scrollbar(main_frame,orient=VERTICAL,command=my_canvas.yview)
y_scrollbar.pack(side=RIGHT,fill=Y)

# Configure the canvas
my_canvas.configure(yscrollcommand=y_scrollbar.set)
my_canvas.bind("<Configure>",lambda e: my_canvas.config(scrollregion= my_canvas.bbox(ALL)))

# Create Another Frame INSIDE the Canvas
second_frame = Frame(my_canvas)

# Add that New Frame a Window In The Canvas
my_canvas.create_window((0,0),window= second_frame, anchor="nw")

# 移除无用的未使用组件
# listbox = Listbox()
# vertical scrollbar
# scrollbar = Scrollbar(orient="vertical", command = listbox.yview)

def build():
    # 支持根据输入数量批量创建图表
    count = int(frames_number_box.get())
    for _ in range(count):
        build_graph(second_frame)

main_button = Button(top_frame, text="Calculate", width=15, height=3)
main_button.config(command=build)
main_button.pack()

window.mainloop() # showing main window

关键改动说明:

  • 调整图表部件的pack参数为side=tk.TOP, fill=tk.X,实现垂直堆叠并适配容器宽度
  • 在build_graph末尾添加滚动区域更新逻辑,确保Canvas能识别新增内容后的高度变化
  • 优化build函数,支持根据输入框数值批量创建图表
  • 删除代码中未使用的listbox和多余滚动条定义

二、无滚动条放置最多20个图表的替代方案

如果不想使用滚动条,以下两种方案更实用:

  • Notebook标签页:每个图表放在独立标签页中,用户通过切换标签查看内容,适合需要独立查看单图表的场景,是20个图表的最优选择。
  • 网格自动换行布局:用grid布局设置固定列数(如4列),让图表自动横向填充后换行,仅适合高分辨率大屏场景。

Notebook标签页示例代码片段

# 需额外导入ttk模块
from tkinter import ttk

# 创建Notebook组件替换原有Canvas布局
main_frame = Frame(window)
main_frame.pack(fill=BOTH, expand=1)
notebook = ttk.Notebook(main_frame)
notebook.pack(fill=BOTH, expand=1)

# 修改build_graph函数,将图表添加到新标签页
def build_graph(notebook):
    figure3 = plt.Figure(figsize=(5, 4), dpi=100)
    ax3 = figure3.add_subplot(111)
    x = [i for i in range(100)]
    points = [i for i in range(100)]
    ax3.plot(x, points, color='b')
    # 创建标签页容器
    tab_frame = Frame(notebook)
    scatter3 = FigureCanvasTkAgg(figure3, tab_frame)
    scatter3.get_tk_widget().pack(fill=BOTH, expand=1)
    # 添加新标签页
    notebook.add(tab_frame, text=f"Chart {notebook.index('end')+1}")

# 修改build函数
def build():
    count = int(frames_number_box.get())
    for _ in range(count):
        build_graph(notebook)

这种方式无需滚动条,用户可快速切换查看任意图表,体验优于滚动大量图表。

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:34:56