more optional customization if you need call this function by tkinter grid.
import tkinter as tk
from tkinter import *
from tkinter import Scrollbar
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
class ScrollableTkAggY(FigureCanvasTkAgg):
def __init__(self, figure, master, *args, **kwargs):
# --- create canvas with scrollbar ---
self.canvas = tk.Canvas(master)
self.canvas.grid(row=0, column=0, sticky=tk.NSEW)
self.canvas.rowconfigure(0, weight=1)
self.canvas.columnconfigure(0, weight=1)
self.fig_wrapper = tk.Frame(self.canvas)
self.fig_wrapper.grid(row=0, column=0, sticky=tk.NSEW)
self.fig_wrapper.rowconfigure(0, weight=1)
self.fig_wrapper.columnconfigure(0, weight=1)
super(ScrollableTkAggY, self).__init__(figure, master=self.fig_wrapper, *args, **kwargs)
self.tkagg = self.get_tk_widget()
self.tkagg.grid(row=0, column=0, sticky=tk.NSEW)
self.vbar = Scrollbar(self.canvas, orient=tk.VERTICAL, command=self.canvas.yview)
self.vbar.grid(row=0, column=1, sticky=tk.NS)
self.canvas.configure(yscrollcommand=self.vbar.set, scrollregion=self.canvas.bbox(tk.ALL))
# when all widgets are in canvas
self.canvas.bind('<Configure>', self.on_configure)
# --- put frame in canvas ---
self.canvas_frame = self.canvas.create_window((0, 0), window=self.fig_wrapper, anchor=tk.NW)
ScrollableTkAggY_meths = vars(ScrollableTkAggY).keys()
methods = vars(Pack).keys() | vars(Grid).keys() | vars(Place).keys()
methods = methods.difference(ScrollableTkAggY_meths)
for m in methods:
if m[0] != '_' and m != 'config' and m != 'configure':
setattr(self, m, getattr(self.canvas, m))
def __str__(self):
return str(self.canvas)
# expand canvas_frame when canvas changes its size
def on_configure(self, event):
# update scrollregion after starting 'mainloop'
self.canvas.configure(scrollregion=self.canvas.bbox(tk.ALL))
# when all widgets are in canvas
canvas_width = event.width
self.canvas.itemconfig(self.canvas_frame, width=canvas_width - 20)
class ScrollableTkAggX(FigureCanvasTkAgg):
def __init__(self, figure, master, *args, **kwargs):
# --- create canvas with scrollbar ---
self.canvas = tk.Canvas(master)
self.canvas.grid(row=0, column=0, sticky=tk.NSEW)
self.canvas.rowconfigure(0, weight=1)
self.canvas.columnconfigure(0, weight=1)
self.fig_wrapper = tk.Frame(self.canvas)
self.fig_wrapper.grid(row=0, column=0, sticky=tk.NSEW)
self.fig_wrapper.rowconfigure(0, weight=1)
self.fig_wrapper.columnconfigure(0, weight=1)
super(ScrollableTkAggX, self).__init__(figure, master=self.fig_wrapper, *args, **kwargs)
self.tkagg = self.get_tk_widget()
self.tkagg.grid(row=0, column=0, sticky=tk.NSEW)
self.hbar = Scrollbar(self.canvas, orient=tk.HORIZONTAL, command=self.canvas.xview)
self.hbar.grid(row=1, column=0, sticky=tk.EW)
self.canvas.configure(xscrollcommand=self.hbar.set, scrollregion=self.canvas.bbox(tk.ALL))
# when all widgets are in canvas
self.canvas.bind('<Configure>', self.on_configure)
# --- put frame in canvas ---
self.canvas_frame = self.canvas.create_window((0, 0), window=self.fig_wrapper, anchor=tk.NW)
ScrollableTkAggX_meths = vars(ScrollableTkAggX).keys()
methods = vars(Pack).keys() | vars(Grid).keys() | vars(Place).keys()
methods = methods.difference(ScrollableTkAggX_meths)
for m in methods:
if m[0] != '_' and m != 'config' and m != 'configure':
setattr(self, m, getattr(self.canvas, m))
def __str__(self):
return str(self.canvas)
# expand canvas_frame when canvas changes its size
def on_configure(self, event):
# update scrollregion after starting 'mainloop'
self.canvas.configure(scrollregion=self.canvas.bbox(tk.ALL))
# when all widgets are in canvas
canvas_height = event.height
self.canvas.itemconfig(self.canvas_frame, height=canvas_height - 20)
class mclass:
def __init__(self, window):
self.figY = Figure(figsize=(10, 30))
self.axesY = self.figY.subplots(ncols=3, nrows=10)
self.figX = Figure(figsize=(30, 10))
self.axesX = self.figX.subplots(ncols=10, nrows=3)
self.canvasY = ScrollableTkAggY(figure=self.figY, master=window)
self.canvasY.grid(row=0, column=0, sticky='nsew')
self.canvasY.rowconfigure(0, weight=1)
self.canvasY.columnconfigure(0, weight=1)
self.canvasX = ScrollableTkAggX(figure=self.figX, master=window)
self.canvasX.grid(row=1, column=0, sticky='nsew')
self.canvasX.rowconfigure(0, weight=1)
self.canvasX.columnconfigure(0, weight=1)
window.geometry("%dx%d+0+0" % (800, 600))
window.focus_set()
self.do_plot()
def do_plot(self):
# Color used in mpl online documentation.
mpl_grey_rvb = (51. / 255., 51. / 255., 51. / 255.)
self.figY.suptitle("Matplotlib's math rendering engine ScrollableTkAggY",
color=mpl_grey_rvb, fontsize=14, weight='bold')
self.figX.suptitle("Matplotlib's math rendering engine ScrollableTkAggX",
color=mpl_grey_rvb, fontsize=14, weight='bold')
# Plotting features demonstration formulae
for i in range(self.axesY.shape[0]):
for j in range(self.axesY.shape[1]):
self.axesY[i, j].set_xlabel("xlabel")
self.axesY[i, j].set_ylabel("ylabel")
self.figY.tight_layout()
self.canvasY.draw()
for i in range(self.axesX.shape[0]):
for j in range(self.axesX.shape[1]):
self.axesX[i, j].set_xlabel("xlabel")
self.axesX[i, j].set_ylabel("ylabel")
self.figX.tight_layout()
self.canvasX.draw()
if __name__ == '__main__':
window = Tk()
start = mclass(window)
window.rowconfigure(0, weight=1)
window.rowconfigure(1, weight=1)
window.columnconfigure(0, weight=1)
# window.columnconfigure(1, weight=1)
window.mainloop()
and this the result.
enter image description here