I would like to draw multiple plots with Matplotlib, add them to a Tkinter frame (stack them one below the other), and be able to scroll vertically between the plots. Each plot shold fill the x-direction, and have a minimum y-height, so that if the total height of the multiple plots is above the height of the window, the scroll should be enabled.
I have found a way to scroll a single large figure (made of multiple subplots), but I am constrained to use a library which cannot produce subplots, so my idea was to stack the single plots one below the other, considering them as Tkinter widgets.
So far, I have the following, but as you can see the scrollbar is present but doesn't work. Any insight would be useful.
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
f = Figure()
a = f.add_subplot(111)
g = Figure()
b = g.add_subplot(111)
from tkinter import *
root=Tk()
frame=Frame(root)
frame.pack(expand=True, fill=BOTH)
canvas=Canvas(frame,bg='#FFFFFF',scrollregion=(0,0,500,500))
vbar=Scrollbar(frame,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config()
canvas.config(yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)
middle = Frame(canvas, bg="yellow")
middle.pack(side="bottom", expand=True, fill="both")
canvas_1 = FigureCanvasTkAgg(f, middle)
canvas_1.get_tk_widget().pack(expand=True, fill="both")
canvas_1.draw()
bottom = Frame(canvas, bg="blue")
bottom.pack(side="bottom", expand=True, fill="both")
canvas_2 = FigureCanvasTkAgg(g, bottom)
canvas_2.get_tk_widget().pack(expand=True, fill="both")
canvas_2.draw()
root.mainloop()
which produces:
Using middle.pack()
to put frame middle
(same for frame bottom
) will not activate the scrollbar.
You need to put frame middle
into the canvas using canvas.create_window()
instead and put the two plots into frame middle
(so frame bottom
can be removed).
Below is the modified code:
from tkinter import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
f = Figure()
a = f.add_subplot(111)
g = Figure()
b = g.add_subplot(111)
root = Tk()
frame = Frame(root)
frame.pack(expand=True, fill=BOTH)
canvas = Canvas(frame, bg='#FFFFFF', width=700, height=700,
highlightthickness=0)
vbar = Scrollbar(frame, orient=VERTICAL, command=canvas.yview)
vbar.pack(side=RIGHT, fill=Y)
canvas.config(yscrollcommand=vbar.set)
canvas.pack(side=LEFT, expand=True, fill=BOTH)
middle = Frame(canvas, bg="yellow")
# put the frame using .create_window()
canvas.create_window(0, 0, window=middle, anchor='nw')
# put the two plots into same frame "middle"
canvas_1 = FigureCanvasTkAgg(f, middle)
canvas_1.get_tk_widget().pack(expand=True, fill=BOTH)
canvas_1.draw()
canvas_2 = FigureCanvasTkAgg(g, middle)
canvas_2.get_tk_widget().pack(expand=True, fill=BOTH)
canvas_2.draw()
# update canvas scrollregion option whenever the frame is resized
middle.bind(
'<Configure>',
lambda e: canvas.config(scrollregion=canvas.bbox('all'))
)
root.mainloop()
Result: