【问题标题】:Embedding Matplotlib and Slider in Tk window在 Tk 窗口中嵌入 Matplotlib 和 Slider
【发布时间】:2016-12-05 15:17:33
【问题描述】:

我正在尝试在 tkinter GUI 中嵌入一个 matplotlib 窗口,但我无法让“滑块”小部件显示出来。事实上,下面的代码确实显示了一个嵌入的图像,但图像本身的行为就像一个滑块,如果你点击它!

我已经尝试使用这个问题的想法

Placing plot on Tkinter main window in Python

import matplotlib
matplotlib.use('TkAgg')
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.widgets import Slider
import Tkinter as tk


class Embed:

    def __init__(self, root):

        self.root = root
        self.plot = Plotting(self.root)
        self.a = np.array([[1,2,3],[2,3,4],[3,4,5]])
        self.b = np.array([[1,2,3],[4,5,6],[7,8,9]])
        self.ctuple = (self.a,self.b)
        self.cube = np.dstack(self.ctuple)
        self.button = tk.Button(root, text="check", command=lambda: self.plot.plot(self.cube))
        self.button.pack()

class Plotting:

    def __init__(self, root):

        self.root = root

    def plot(self, cube, axis=2, **kwargs):

        fig = Figure(figsize=(6,6))
        ax = fig.add_subplot(111)
        s = [slice(0,1) if i == axis else slice(None) for i in xrange(3)]
        im = cube[s].squeeze()

        l = ax.imshow(im, **kwargs)
        canvas = FigureCanvasTkAgg(fig, self.root)
        canvas.get_tk_widget().pack()
        canvas.draw()
        slider = Slider(ax, 'Axis %i index' % axis, 0, cube.shape[axis] - 1,
                    valinit=0, valfmt='%i')

        def update(val):
            ind = int(slider.val)
            s = [slice(ind, ind + 1) if i == axis else slice(None)
             for i in xrange(3)]
            im = cube[s].squeeze()
            l.set_data(im, **kwargs)
            canvas.draw()

        slider.on_changed(update)

if __name__ == '__main__':

    root = tk.Tk()
    app = Embed(root)
    root.mainloop()
    root.destroy()

非常感谢任何帮助!

【问题讨论】:

    标签: python python-2.7 matplotlib tkinter


    【解决方案1】:

    我不知道你的代码是做什么的。我试图尽可能少地改变它:

    import matplotlib
    matplotlib.use('TkAgg')
    import numpy as np
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    from matplotlib.figure import Figure
    import Tkinter as Tk
    import matplotlib.pyplot as plt
    
    
    class Embed:
    
        def __init__(self, root_):
            self.root = root_
            self.a = np.array([[1, 2, 3], [2, 3, 4], [3, 4, 5]])
            self.b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
            self.c = np.array([[1, 4, 7], [4, 7, 10], [7, 10, 13]])
            self.ctuple = (self.a, self.b)
            self.cube = np.dstack(self.ctuple)
            self.cube = np.dstack([self.cube, self.c])
            self.plot = Plotting(self.root, self.cube)
            self.button = Tk.Button(root, text="check", command=lambda: self.plot.plot())
            self.button.pack()
    
    
    class Plotting:
        def __init__(self, root, cube):
            self.root = root
            self.fig = Figure(figsize=(6, 6))
            self.ax = self.fig.add_subplot(111)
            self.cube = cube
            self.slider = Tk.Scale(
                self.root, from_=0, to=cube.shape[2] - 1, resolution=0.01, orient=Tk.HORIZONTAL, command=self.update
            )
            # self.slider.on_changed(self.update)
            self.slider.pack()
            self.plotted = False
            self.l = None
            self.canvas = None
            plt.show()
    
        def plot(self, **kwargs):
            self.plotted = True
            s = [slice(0, 1) if i == 2 else slice(None) for i in xrange(3)]
            im = self.cube[s].squeeze()
            self.l = self.ax.imshow(im, **kwargs)
            self.canvas = FigureCanvasTkAgg(self.fig, self.root)
            self.canvas.get_tk_widget().pack()
            self.canvas.draw()
    
        def update(self, val):
            ind = int(self.slider.get())
            s = [slice(ind, ind + 1) if i == 2 else slice(None) for i in xrange(3)]
            if self.plotted:
                im = self.cube[s].squeeze()
                self.l.set_data(im)
                self.canvas.draw()
    
    
    if __name__ == '__main__':
        root = Tk.Tk()
        app = Embed(root)
        root.mainloop()
        root.destroy()
    

    【讨论】:

    • 感谢您的回复,我正在尝试在我的 tkinter gui 中嵌入一个 mpl 窗口,该窗口使用滑块在 3d 数组中移动。这段代码说明了我想嵌入的pastebin.com/AxnUZ7EJ,它会在单击按钮时生成一个新窗口,并带有一个滚动条来滚动数组。目前只有两个虚拟数组
    • 那么问题出在哪里? pastebin.com/AxnUZ7EJ 为我工作。你检查我的代码了吗?
    • 抱歉,我确实检查了您的代码并认为它​​没有显示滑块,但再次检查后我可以看到它确实显示了。不知道我第一次做了什么...感谢您的帮助“root_”中的下划线是什么意思?
    • 我使用 PyCharm IDE。我推荐它(社区版)。它具有检查代码的功能。当你为全局 root = Tk.Tk() 和函数内部编写相同的变量名时,PyCharm 说它可以隐藏全局。名称后的下划线表示它是“私有”或内部变量。见:python.org/dev/peps/pep-0008/#descriptive-naming-styles
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 2016-04-22
    • 2014-03-21
    • 2011-05-27
    相关资源
    最近更新 更多