繁体   English   中英

matplotlib-将滑块动态添加到图形

[英]matplotlib - Add sliders to a figure dynamically

基于这个那个例子,我想滑块动态地添加到数字(在绘制对象的功能)。

将创建滑块并将其添加到for循环内,并且每次都会创建一个新的update()函数。

问题:滑块不响应任何鼠标输入!

任何想法如何解决这个问题?

图形

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

class Plotter:
    def __init__(self):
        self.fig, self.ax = plt.subplots()

    def plot(self, obj):
        self.obj = obj
        self.l = plt.plot(obj.t,obj.series())
        vars = obj.get_variables()
        plt.subplots_adjust(bottom=0.03*(len(vars)+2))
        for i,var in enumerate(vars):
            self.add_slider(i*0.03, var[0], var[1], var[2])
        plt.show()

    def add_slider(self, pos, name, min, max):
        ax = plt.axes([0.1, 0.02+pos, 0.8, 0.02], axisbg='lightgoldenrodyellow')
        slider = Slider(ax, name, min, max, valinit=getattr(self.obj, name))
        def update(val):
            setattr(self.obj, name, val)
            self.l.set_ydata(self.obj.series())
            self.fig.canvas.draw_idle()
        slider.on_changed(update)

class SinFunction:
    def __init__(self):
        self.freq = 1.0
        self.amp = 0.5
        self.t = np.arange(0.0, 1.0, 0.001)

    def series(self):
        return self.amp*np.sin(2*np.pi*self.freq*self.t)

    def get_variables(self):
        return [
            ('freq', 0.1, 10),
            ('amp', 0.1, 1)
        ]

Plotter().plot(SinFunction())

Plotter类的plot方法中,您将以这种方式获取Plotter所有序列 self.l = plt.plot(obj.t,obj.series())因此在self.l您具有对象列表,并且不是对象本身。 您可以有多个行。

add_slider方法中,应将self.l.set_ydata(self.obj.series())更改为self.l[0].set_ydata(self.obj.series())以使用对象的方法。 在这种情况下, self.l只有一个对象,但您可以拥有更多。 请考虑到这一点。

另外,为了使滑块相应地起作用(请参见下面的注释),似乎它们需要处于同一范围内。 要在相同范围内使用滑块,可以创建一个sliders attribute

最终代码应为:

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

class Plotter:
    def __init__(self):
        self.fig, self.ax = plt.subplots()

    def plot(self, obj):
        self.obj = obj
        self.l = plt.plot(obj.t,obj.series())
        _vars = obj.get_variables()
        plt.subplots_adjust(bottom=0.03*(len(_vars)+2))
        self.sliders = []
        for i,var in enumerate(_vars):
            self.add_slider(i*0.03, var[0], var[1], var[2])
        plt.show()

    def add_slider(self, pos, name, min, max):
        ax = plt.axes([0.1, 0.02+pos, 0.8, 0.02], axisbg='lightgoldenrodyellow')
        slider = Slider(ax, name, min, max, valinit=getattr(self.obj, name))
        self.sliders.append(slider)
        def update(val):
            setattr(self.obj, name, val)
            self.l[0].set_ydata(self.obj.series())
            self.fig.canvas.draw_idle()
        slider.on_changed(update)

class SinFunction:
    def __init__(self):
        self.freq = 1.0
        self.amp = 0.5
        self.t = np.arange(0.0, 1.0, 0.001)

    def series(self):
        return self.amp*np.sin(2*np.pi*self.freq*self.t)

    def get_variables(self):
        return [
            ('freq', 0.1, 10),
            ('amp', 0.1, 1)
        ]

k = Plotter()
k.plot(SinFunction())

这个版本适用于Python 2和Python 3。

PD:与Python 3相比,我在Python 2上看到了不同的行为。我不知道它是否与Python或Matplotlib有关……...?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM