Python Forum
[Tkinter] Fixate graphs on scrollable canvas
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Fixate graphs on scrollable canvas
#1
The idea is that I want the graphs only to appear on the scrollable canvas next to the previous graph. At this moment when I create another graph it will just be plotted outside the canvas. Note that I just set the scrollregion to a random high number. It actually needs to grow with each extra graph added. However, I did not figure out how.

Anyone knows what I am doing wrong here? Huh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import tkinter as tk
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
class Example:
    def __init__(self, master):
        self.clicks = 0
        self.master = master
        self.frame= tk.Frame(master,width=600,height=100,background="green")
        self.canv = tk.Canvas(master, width=600, height=400,background="blue",scrollregion=(0,0,2000,2000))
 
        button = tk.Button(master,text='click',command= lambda: self.select(master))
 
        self.scrollY = tk.Scrollbar(master, orient=tk.VERTICAL,
                                    command=self.canv.yview)
        self.scrollX = tk.Scrollbar(master, orient=tk.HORIZONTAL,
                                    command=self.canv.xview)
 
        self.canv['xscrollcommand'] = self.scrollX.set
        self.canv['yscrollcommand'] = self.scrollY.set
 
        self.frame.grid(row=0,column=0,rowspan=3)
        self.scrollY.grid(row=3, column=1, sticky=tk.N+tk.S)
        button.grid(row=2,column=0,padx=10,sticky=tk.NW)
        self.scrollX.grid(row=4, column=0, sticky=tk.E+tk.W)
        self.canv.grid(row=3, column=0)
    def select(self,master):
        self.clicks +=1
        shape = np.random.randint(0,2,[5,5])
        lon = np.arange(5)
        lat = np.arange(5)
        fig = Figure(figsize=(4,4))
        ax = fig.add_subplot(111)
        c = ax.pcolor(lon,lat,shape)
        fig.colorbar(c,ax=ax,fraction=0.046,pad=0.04)
        canvas = FigureCanvasTkAgg(fig,self.canv)
 
        canvas.get_tk_widget().grid(row=0,column=self.clicks)
 
if __name__ == "__main__":
    root=tk.Tk()
    Example(root)
    root.mainloop()
Reply
#2
The following changes will widen your frame and canvas.
You can fix the graph positioning math so that the second one uses the proper coordinates.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import tkinter as tk
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
 
 
class Example:
    def __init__(self, master):
        self.clicks = 0
        self.master = master
 
        self.frame_width = 600
        self.frame_height = 100
 
        self.canvas_width = 600
        self.canvas_height = 400
 
        self.frame= tk.Frame(master, width=self.frame_width, height=self.frame_height,
            background="green")
        self.canv = tk.Canvas(master, width=self.canvas_width, height=self.canvas_height,
            background="blue",scrollregion=(0,0,2000,2000))
  
        button = tk.Button(master,text='click',command= lambda: self.select(master))
  
        self.scrollY = tk.Scrollbar(master, orient=tk.VERTICAL,
                                    command=self.canv.yview)
        self.scrollX = tk.Scrollbar(master, orient=tk.HORIZONTAL,
                                    command=self.canv.xview)
  
        self.canv['xscrollcommand'] = self.scrollX.set
        self.canv['yscrollcommand'] = self.scrollY.set
  
        self.frame.grid(row=0,column=0,rowspan=3)
        self.scrollY.grid(row=3, column=1, sticky=tk.N+tk.S)
        button.grid(row=2,column=0,padx=10,sticky=tk.NW)
        self.scrollX.grid(row=4, column=0, sticky=tk.E+tk.W)
        self.canv.grid(row=3, column=0)
 
    def select(self,master):
        if self.clicks > 0:       
            self.frame_width += 600
            self.canvas_width += 600
            self.frame.configure(width=self.frame_width)
            self.canvas.configure(width=self.canvas_width)
 
        self.clicks +=1
 
        shape = np.random.randint(0,2,[5,5])
        lon = np.arange(5)
        lat = np.arange(5)
        fig = Figure(figsize=(4,4))
        ax = fig.add_subplot(111)
        c = ax.pcolor(lon,lat,shape)
        fig.colorbar(c,ax=ax,fraction=0.046,pad=0.04)
        canvas = FigureCanvasTkAgg(fig,self.canv)
  
        canvas.get_tk_widget().grid(row=0,column=self.clicks)
  
 
if __name__ == "__main__":
    root=tk.Tk()
    Example(root)
    root.mainloop()
Reply
#3
Thank you very much for your response! However, I don't want the size of the canvas or frame to expand. That's why I used a scrollable canvas. Or is this not possible?
Reply
#4
Ok, misunderstood. You can use scrollable canvas.
To do this, I think you need to attach the scrollbars to the frame, not master, and not the canvas.
Reply
#5
Thanks! I tried that and I also set the canvas attached to the frame. That did not work, so I tried to also create a new frame attached to the canvas and attached to canvas with graph to that new frame.
And it is still not working, I really don't understand why

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import tkinter as tk
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
class Example:
    def __init__(self, master):
        self.clicks = 0
        self.master = master
        self.frame= tk.Frame(master,width=600,height=400,background="green")
        self.canv = tk.Canvas(self.frame, width=600, height=400,background="blue",scrollregion=(0,0,2000,2000))
        button = tk.Button(master,text='click',command= lambda: self.select(master))
  
        self.scrollY = tk.Scrollbar(self.frame, orient=tk.VERTICAL,
                                    command=self.canv.yview)
        self.scrollX = tk.Scrollbar(self.frame, orient=tk.HORIZONTAL,
                                    command=self.canv.xview)
  
        self.canv['xscrollcommand'] = self.scrollX.set
        self.canv['yscrollcommand'] = self.scrollY.set
  
        self.frame.grid(row=0,column=0,rowspan=3)
        self.scrollY.grid(row=3, column=1, sticky=tk.N+tk.S)
        button.grid(row=2,column=0,padx=10,sticky=tk.NW)
        self.scrollX.grid(row=4, column=0, sticky=tk.E+tk.W)
        self.canv.grid(row=3, column=0)
        self.framesub = tk.Frame(self.canv)
        self.framesub.bind("<Configure>",self.canv.configure(scrollregion=self.canv.bbox("all"),width=200,height=200))
         
    def select(self,master):
        self.clicks +=1
 
        shape = np.random.randint(0,2,[5,5])
        lon = np.arange(5)
        lat = np.arange(5)
        fig = Figure(figsize=(4,4))
        ax = fig.add_subplot(111)
        c = ax.pcolor(lon,lat,shape)
        fig.colorbar(c,ax=ax,fraction=0.046,pad=0.04)
        canvas1= FigureCanvasTkAgg(fig,self.framesub)
        #framesub.grid(row=0,column=self.clicks)
        canvas1.get_tk_widget().grid(row=0,column=0)
 
 
if __name__ == "__main__":
    root=tk.Tk()
    Example(root)
    root.mainloop()
Reply
#6
I got it working!! Thank you :-)

Here's how it looks now (sorry, may have changed the names a bit):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import tkinter as tk
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
 
class tkintertool:
    def __init__(self,master):
        self.clicks= 0
        self.master = master
         
        master.geometry("2000x1000")
         
        self.myframe = tk.Frame(master,relief=tk.GROOVE,width=500,height=300,bd=1,background="blue")
        self.myframe.grid(row=0,column=0)
 
        self.canvas=tk.Canvas(self.myframe,background="green")
        self.frame=tk.Frame(self.canvas,background="red")
         
        button = tk.Button(master,text='click',command=lambda: self.data())
         
        myscrollbar=tk.Scrollbar(self.myframe,orient="vertical",command=self.canvas.yview)
        myscrollbarx=tk.Scrollbar(self.myframe,orient="horizontal",command=self.canvas.xview)
        self.canvas.configure(yscrollcommand=myscrollbar.set,xscrollcommand=myscrollbarx.set)
 
        myscrollbar.pack(side="right",fill="y")
        myscrollbarx.pack(side="bottom",fill="x")
        button.grid(row=2,column=0)
        self.canvas.pack(side="left")
        self.canvas.create_window((0,0),window=self.frame,anchor='nw')
        self.frame.bind("<Configure>",self.myfunction())
        size = (self.frame.winfo_reqwidth(), self.frame.winfo_reqheight())
        print(size)
    def data(self):
        self.clicks+=1
        self.frame.bind("<Configure>",self.myfunction())
        shape = np.random.randint(0,(3),[5,5])
        lon = np.arange(5)
        lat = np.arange(5)
        fig = Figure(figsize=(4,4))
        ax = fig.add_subplot(111)
        c = ax.pcolor(lon,lat,shape)
        fig.colorbar(c,ax=ax,fraction=0.046,pad=0.04)
        canvas = FigureCanvasTkAgg(fig,self.frame)
        canvas.get_tk_widget().grid(row=0,column=(self.clicks))
    #    self.canvas.config(scrollregion='0 0 %s %s' % size)
 
    def myfunction(self):
        self.canvas.configure(scrollregion=(0,0,288*(self.clicks),288),width=500,height=300)
         
root = tk.Tk()
my_gui = tkintertool(root)
root.mainloop()
Reply
#7
You're welcome, please click Set Solved
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] PyQt5 drawing on scrollable area HeinKurz 3 2,356 Mar-28-2023, 12:58 PM
Last Post: Axel_Erfurt
  [Tkinter] Scrollable buttons with an add/delete button Clich3 5 5,688 Jun-16-2022, 07:19 PM
Last Post: rob101
  [Tkinter] How to create scrollable frame mandiatutti 7 8,339 Aug-07-2021, 03:34 PM
Last Post: deanhystad
Question [Tkinter] Scrollable Treeview: change behavior of Prior/Next keys? RockDoctor 2 4,501 Apr-10-2021, 05:40 PM
Last Post: RockDoctor
  Scrollable big image in a window (TKinter) Prospekteur 3 5,942 Sep-14-2020, 03:06 AM
Last Post: Larz60+
  [Tkinter] Resizing image inside Canvas (with Canvas' resize) Gupi 2 26,544 Jun-04-2019, 05:05 AM
Last Post: Gupi
  [Tkinter] ListBox not contained or scrollable kellykimble 6 7,257 Apr-05-2018, 11:59 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020