Home > OS >  Making an scrollable plot in tkinter
Making an scrollable plot in tkinter

Time:12-30

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()
  • Related