Tkinter FigureCanvasTkAgg滚动条可正常使用,但从滚动视图中删除了子图

时间:2019-08-09 16:15:53

标签: python matplotlib tkinter scrollbar frame

我使用matplotlib创建了一个具有可变数量子图的图形。我已在包含该图形的页面上添加了一个滚动条,以便用户可以滚动浏览各个图形。通过多次尝试,滚动条现在可以正常工作,但是,该图似乎在页面原始底部所在的位置被切断,从而使某些子图被切断(参见图片)。

下面的示例代码应该模仿我遇到的问题。但是,下面的代码似乎有其自身的问题:它不会像在我的原始代码中那样拉伸图形,以重现附加的图像。但是,它仍然应该给您一个想法-我希望图形能够超出常规框架的大小,并希望滚动条允许用户查看所有子图。

import tkinter as tk
from tkinter import *
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure



f = Figure(figsize = (1,1), dpi = 100)

a = []

for i in range(0,20):

    a.append(f.add_subplot(20,1,i+1))

f.set_figheight(60)
f.set_figwidth(14)

for i in range(0,20):

    a[i].plot([1,2,3,4,5],[1,2,3,4,5])
    a[i].set_title('Graph ' + str(i+1))



class App(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)

        container.pack(side = "top", fill = "both", expand = True)
        container.grid_columnconfigure(0,weight=1)
        container.grid_rowconfigure(0,weight = 1)

        self.minsize(620,400)

        self.geometry("{0}x{1}+0+0".format(self.winfo_screenwidth(), self.winfo_screenheight()))

        self.update_idletasks()


        self.frames = {}

        for F in (StartPage, PageTwo):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row = 0, column = 0, sticky = 'nsew')

        self.show_frame(StartPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        button_p1 = tk.Button(self, text = "PageTwo →",
                              command = lambda: controller.show_frame(PageTwo))
        button_p1.pack(side = TOP, fill = X)

        label = tk.Label(self, text = "Start Page")
        label.pack(fill = X, expand = True)


class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)


        button_1 = tk.Button(self, text = "← Start Page",
                         command = lambda: controller.show_frame(StartPage))
        button_1.pack(side = LEFT, anchor = N)

        label_p1 = tk.Label(self, text = "PageTwo")
        label_p1.pack()

        canvas = FigureCanvasTkAgg(f,self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.BOTTOM,fill=tk.X,expand = True)

        scroll=Scrollbar(canvas.get_tk_widget())
        scroll.config(command=canvas.get_tk_widget().yview)
        scroll.pack(side = RIGHT, fill=Y)
        canvas.get_tk_widget().pack(side = LEFT, expand = YES, fill = BOTH)
        canvas.get_tk_widget().config(yscrollcommand=scroll.set)


        canvas.get_tk_widget().config(scrollregion=(0,0,1000,10000),confine=True)

app = App()

app.mainloop()

过去几天,我一直在寻找解决方案,但是没有找到专门针对我的问题的解决方案,或者我可以更改以适应的解决方案。

Image - Cut off subplots

我认为解决方案应该增加框架的高度或类似的高度-我试图做到这一点没有运气。

我希望所有其他页面的窗口大小保持不变-我只想增加PageTwo的高度以用于滚动条。

1 个答案:

答案 0 :(得分:0)

此解决方案可能无法解决在所有轴上滚动的问题,但是我发现了一个错误,该错误可能导致子图被过早切断。我要进行的更改是在Scrollbar对象的实例化中进行的。传递画布对象而不是小部件可以解决我遇到的相同问题。

PageTwo(tk.Frame)类:

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)


    button_1 = tk.Button(self, text = "← Start Page",
                     command = lambda: controller.show_frame(StartPage))
    button_1.pack(side = LEFT, anchor = N)

    label_p1 = tk.Label(self, text = "PageTwo")
    label_p1.pack()

    canvas = FigureCanvasTkAgg(f,self)
    canvas.draw()
    canvas.get_tk_widget().pack(side=tk.BOTTOM,fill=tk.X,expand = True)

    scroll=Scrollbar(canvas)
    scroll.config(command=canvas.get_tk_widget().yview)
    scroll.pack(side = RIGHT, fill=Y)
    canvas.get_tk_widget().pack(side = LEFT, expand = YES, fill = BOTH)
    canvas.get_tk_widget().config(yscrollcommand=scroll.set)


    canvas.get_tk_widget().config(scrollregion=(0,0,1000,10000),confine=True)