Python Matplotlib 滑块小部件不更新

2 投票
1 回答
2429 浏览
提问于 2025-04-17 13:12

我想使用多个 matplotlib 画布,每个画布上都有数据和一个滑块控件。问题是这些滑块控件没有正确更新(看起来鼠标事件没有被发送或者其他什么原因)。

这是我现在的代码:

import matplotlib
matplotlib.use('TkAgg')

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.widgets import Slider

class PlotWidget( Tk.Frame ):

    def __init__(self, master):
        Tk.Frame.__init__(self, master)
        self.figure = Figure(figsize=(5,4), dpi=75)
        self.canvas = FigureCanvasTkAgg(self.figure, self)

        self.frame = self.canvas.get_tk_widget()
        self.frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        self.canvas.show()

    def add_slider(self):
       a = self.figure.add_axes([0.25, 0.1, 0.65, 0.03], axisbg='lightgoldenrodyellow')
       s = Slider( a, 'range', 0.1, 30.0, valinit=5)
       self.canvas.show()



root = Tk.Tk()

option = 1    

if option == 1 or option = 2:
     w =  PlotWidget(root)
     w.pack()
     figure = w.figure
else:
     f = Tk.Frame(root, bd = 6, bg='red')
     figure = matplotlib.figure.Figure(figsize=(5,4), dpi=75)
     canvas = FigureCanvasTkAgg(figure, f)
     canvas.get_tk_widget().pack()
     canvas.show()
     f.pack()


if option = 1:
    w.add_slider()
else:
    a = figure.add_axes([0.25, 0.1, 0.65, 0.03], axisbg='lightgoldenrodyellow')   
    s = Slider( a, 'range', 0.1, 30.0, valinit=5)

Tk.mainloop()

选项 1 不起作用,其他组合在测试脚本中都能正常工作,但在我的应用中,当我在其他位置创建滑块控件时,它也不工作。滑块对鼠标事件没有反应……

我到底漏掉了什么?

1 个回答

2

为了让你的脚本在我的电脑上运行,我做了以下修改。

import matplotlib
from Tkinter import *
matplotlib.use('TkAgg')

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.widgets import Slider

class PlotWidget( Frame ):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.figure = Figure(figsize=(5,4), dpi=75)
        self.canvas = FigureCanvasTkAgg(self.figure, self)

        self.frame = self.canvas.get_tk_widget()
        self.frame.pack(side=TOP, fill=BOTH, expand=1)
        self.canvas.show()

    def add_slider(self):
       a = self.figure.add_axes([0.25, 0.1, 0.65, 0.03], axisbg='lightgoldenrodyellow')
       s = Slider( a, 'range', 0.1, 30.0, valinit=5)
       self.canvas.show()



root = Tk()

option = 1

if option == 1 or option == 2:
     w =  PlotWidget(root)
     w.pack()
     figure = w.figure
else:
     f = Frame(root, bd = 6, bg='red')
     figure = matplotlib.figure.Figure(figsize=(5,4), dpi=75)
     canvas = FigureCanvasTkAgg(figure, f)
     canvas.get_tk_widget().pack()
     canvas.show()
     f.pack()


if option == 1:
    w.add_slider()
else:
    a = figure.add_axes([0.25, 0.1, 0.65, 0.03], axisbg='lightgoldenrodyellow')   
    s = Slider( a, 'range', 0.1, 30.0, valinit=5)

root.mainloop()

我觉得选项1不管用是因为滑块(Slider)创建的范围不对。

这个例子 在这里 也是在和图形(figure)以及显示(show)命令同一个范围内创建的。

如果你想把滑块的创建放到一个函数里,你可以让这个函数把滑块返回到函数外面的范围。只需要在add_slider的最后一行加上 return s,然后把 w.add_slider() 改成 s = w.add_slider()

或者你可以把相关的内容存储在和画布(canvas)和图形(figure)同一个范围内,比如 self.slider = Slider( a, 'range', 0.1, 30.0, valinit=5)

这两种方法都能让滑块在鼠标事件发生时更新,当 option = 1 的时候。

撰写回答