13

このデモと同様に、matplotlib スライダーを使用しています。スライダーは現在、小数点以下 2 桁を使用しており、かなり連続しているように感じます (ただし、あるレベルでは離散的である必要があります)。どのレベルが離散的かを判断できますか? 整数ステップ?0.1サイズのステップ?0.5? 私のgoogle-fuは私を失敗させました。

4

2 に答える 2

32

valfmt整数値が必要な場合は、スライダーを作成するときに適切な値を渡すだけです(例valfmt='%0.0f') 。

ただし、非整数のインバーバルが必要な場合は、毎回手動でテキスト値を設定する必要があります。ただし、これを行っても、スライダーはスムーズに進み、離散的な間隔のように「感じる」ことはありません。

次に例を示します。

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],
                                          axisbg='yellow')

        self.slider = Slider(self.sliderax, 'Value', 0, 10, valinit=self.inc)
        self.slider.on_changed(self.update)
        self.slider.drawon = False

        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):
        value = int(value / self.inc) * self.inc
        self.dot.set_data([[value],[value]])
        self.slider.valtext.set_text('{}'.format(value))
        self.fig.canvas.draw()

    def show(self):
        plt.show()

p = ChangingPlot()
p.show()

スライダーを完全に離散値のように「感じ」させたい場合は、サブクラス化できますmatplotlib.widgets.Slider。主な効果はによって制御されますSlider.set_val

その場合、次のようにします。

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)

    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.iteritems():
            func(discrete_val)

そしてそれを使用する完全な例として:

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()

ここに画像の説明を入力してください

于 2012-12-01T15:48:10.053 に答える