I am trying to develop a Tkinter app for plotting multiple signals. Because of the number of signals, I've decided that I would need to add a scrollbar to the window.
What I've done by now is:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from tkinter import *
window=Tk()
fig, axes = plt.subplots(25, 1,sharex=True,figsize=(5, 40))
t=np.linspace(0,1,1000)
for k in range(25):
axes[k].plot(t,np.sin(2*np.pi*t*k))
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.draw()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
window.mainloop()
I've also added the scrollbar, but I couldn't manage to link it to the canvas. Thanks.
CodePudding user response:
According to what I found here (Tkinter scrollbar for frame) :
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from tkinter import *
class VerticalScrolledFrame(Frame):
def __init__(self, parent, *args, **kw):
Frame.__init__(self, parent, *args, **kw)
# Create a canvas object and a vertical scrollbar for scrolling it.
vscrollbar = Scrollbar(self, orient=VERTICAL)
vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
canvas = Canvas(self, bd=0, highlightthickness=0,
yscrollcommand=vscrollbar.set)
canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
vscrollbar.config(command=canvas.yview)
# Reset the view
canvas.xview_moveto(0)
canvas.yview_moveto(0)
# Create a frame inside the canvas which will be scrolled with it.
self.interior = interior = Frame(canvas)
interior_id = canvas.create_window(0, 0, window=interior,
anchor=NW)
# Track changes to the canvas and frame width and sync them,
# also updating the scrollbar.
def _configure_interior(event):
# Update the scrollbars to match the size of the inner frame.
size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
canvas.config(scrollregion="0 0 %s %s" % size)
if interior.winfo_reqwidth() != canvas.winfo_width():
# Update the canvas's width to fit the inner frame.
canvas.config(width=interior.winfo_reqwidth())
interior.bind('<Configure>', _configure_interior)
def _configure_canvas(event):
if interior.winfo_reqwidth() != canvas.winfo_width():
# Update the inner frame's width to fill the canvas.
canvas.itemconfigure(interior_id, width=canvas.winfo_width())
canvas.bind('<Configure>', _configure_canvas)
window=Tk()
frame = VerticalScrolledFrame(window)
frame.pack(fill=BOTH)
fig, axes = plt.subplots(25, 1,sharex=True,figsize=(5, 40))
t=np.linspace(0,1,1000)
for k in range(25):
axes[k].plot(t,np.sin(2*np.pi*t*k))
canvas = FigureCanvasTkAgg(fig, master=frame.interior)
canvas.draw()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
window.mainloop()