[Python] Matplotlib Slider: function set_val does not work following standard prescriptions?

Discussão em 'Python' iniciado por Stack, Maio 21, 2025.

  1. Stack

    Stack Membro Participativo

    I am a beginner with the Slider tool and retrieved a code which used to work but does not anymore. I found a similar code here to test the Slider tool in this answer which provides a self-contained example:

    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.widgets import Slider

    class ChangingPlot(object):
    def __init__(self):
    self.inc = 0.5

    self.fig, self.ax = plt.subplots()
    self.sliderax = self.fig.add_axes([0.2, 0.02, 0.6, 0.03],
    facecolor='yellow')

    self.slider = DiscreteSlider(self.sliderax, 'Value', 0, 10,
    increment=self.inc, valinit=self.inc)
    self.slider.on_changed(self.update)

    x = np.arange(0, 10.5, self.inc)
    self.ax.plot(x, x, 'ro')
    self.dot, = self.ax.plot(self.inc, self.inc, 'bo', markersize=18)

    def update(self, value):
    self.dot.set_data([[value],[value]])
    self.fig.canvas.draw()

    def show(self):
    plt.show()

    class DiscreteSlider(Slider):
    """A matplotlib slider widget with discrete steps."""
    def __init__(self, *args, **kwargs):
    """Identical to Slider.__init__, except for the "increment" kwarg.
    "increment" specifies the step size that the slider will be discritized
    to."""
    self.inc = kwargs.pop('increment', 0.5)
    Slider.__init__(self, *args, **kwargs)
    self.val = 1

    def set_val(self, val):
    discrete_val = int(val / self.inc) * self.inc
    # We can't just call Slider.set_val(self, discrete_val), because this
    # will prevent the slider from updating properly (it will get stuck at
    # the first step and not "slide"). Instead, we'll keep track of the
    # the continuous value as self.val and pass in the discrete value to
    # everything else.
    xy = self.poly.xy
    xy[2] = discrete_val, 1
    xy[3] = discrete_val, 0
    self.poly.xy = xy
    self.valtext.set_text(self.valfmt % discrete_val)
    if self.drawon:
    self.ax.figure.canvas.draw()
    self.val = val
    if not self.eventson:
    return
    for cid, func in self.observers.items():
    func(discrete_val)


    p = ChangingPlot()
    p.show()


    If I copy and paste the example given in this other page in my Python 3.12.9/Matplotlib 3.10.1 environment, I get a failure :


    Cell In[9], line 47, in DiscreteSlider.set_val(self, val)


    45 xy = self.poly.xy
    46 print(type(self.poly.xy),len(xy),xy)
    ---> 47 xy[2] = discrete_val, 1
    48 xy[3] = discrete_val, 0
    49 self.poly.xy = xy




    TypeError: 'tuple' object does not support item assignment
    ​

    The print command returns :


    <class 'tuple'> 2 (0, 0.25)
    ​

    I understand that tuples cannot be modified but this was supposed to work before ? If I test xy length and content, it returns only 2 values while here it addresses the tuple beyond xy[1].

    What has become wrong ? The few examples I found on internet all still use the above syntax.

    I could convert xy to a list, but I still have the problem that xy length is 2 not 4 and these are simple values, not tuples. So I don't understand the structure of self.poly.xy and I don't understand why the standard example does not work, so I cannot play with it to understand its use...

    Thanks for any help

    Continue reading...

Compartilhe esta Página