Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在类中放置带有可控制参数的动画图形_Python_Python 3.x_Matplotlib_Matplotlib Widget - Fatal编程技术网

Python 在类中放置带有可控制参数的动画图形

Python 在类中放置带有可控制参数的动画图形,python,python-3.x,matplotlib,matplotlib-widget,Python,Python 3.x,Matplotlib,Matplotlib Widget,上面截取的想法是有一个动画图形和一组控制其参数的小部件。更改参数应更改正在显示的图形 也就是说,上面的代码不做这些。它是一个不改变的动画图形和两个改变对象内变量的小部件。然而,该计划并没有像预期的那样起作用 首先,图形根本不显示。我不明白为什么。 其次,更改这两个小部件中任何一个的状态都会抛出一个TypeError: import matplotlib.gridspec as gridspec import numpy as np from matplotlib import animatio

上面截取的想法是有一个动画图形和一组控制其参数的小部件。更改参数应更改正在显示的图形

也就是说,上面的代码不做这些。它是一个不改变的动画图形和两个改变对象内变量的小部件。然而,该计划并没有像预期的那样起作用

首先,图形根本不显示。我不明白为什么。 其次,更改这两个小部件中任何一个的状态都会抛出一个
TypeError

import matplotlib.gridspec as gridspec
import numpy as np

from matplotlib import animation
from matplotlib import pyplot as plt
from matplotlib.widgets import Slider, CheckButtons

PI = np.pi

sliderDataList = [{'name': 'Left amplitude', 'min': 0.1, 'max': 8.0, 'init': 2, 'step': 0.01}]
checkboxDataList = [{'name': 'Left wave', 'init': True}]


class CollidingWaves:
    def __init__(self, timeFactor=5, x_range=4 * PI, x_offset=0, y_range=4, y_offset=0, sliderData=[],
                 checkboxData=[], tension=1, massDensity=1):
        self.x_range = x_range
        self.x_offset = x_offset
        self.y_range = y_range
        self.y_offset = y_offset
        self.sliderData = sliderData
        self.checkboxData = checkboxData
        self.tension = tension
        self.massDensity = massDensity
        self.timeFactor = timeFactor
        self.showWave = []
        self.amplitude = 0

        self.fig = plt.figure()

        self.mainGrid = gridspec.GridSpec(2, 1)
        self.graphCell = plt.subplot(self.mainGrid[0, :])
        self.graphCell.set(xlim=(-self.x_range - self.x_offset, self.x_range - self.x_offset),
                           ylim=(-self.y_range - self.y_offset, self.y_range - self.y_offset))

        self.x_data = np.linspace(-self.x_range - self.x_offset, self.x_range - self.x_offset, 512)
        self.y_data = []

        self.lines = [plt.plot([], [])[0] for _ in range(2)]
        self.patches = self.lines

        self.controlCell = self.mainGrid[1, :]
        self.controlGrid = gridspec.GridSpecFromSubplotSpec(1, 7, self.controlCell)

        self.checkboxCell = self.controlGrid[0, 0]
        self.checkboxGrid = gridspec.GridSpecFromSubplotSpec(1, 1, self.checkboxCell)
        self.checkboxes = []
        self.checkboxAx = plt.subplot(self.checkboxGrid[0, 0:1])
        self.checkbox = CheckButtons(self.checkboxAx, tuple(x["name"] for x in self.checkboxData),
                                     tuple(x["init"] for x in self.checkboxData))
        self.checkboxes.append(self.checkbox)

        self.sliderCell = self.controlGrid[0, 2:6]
        self.sliderGrid = gridspec.GridSpecFromSubplotSpec(len(self.sliderData), 1, self.sliderCell)
        self.sliders = []
        for i in range(0, len(self.sliderData)):
            self.sliderAx = plt.subplot(self.sliderGrid[i, 0])
            self.slider = Slider(self.sliderAx, self.sliderData[i]["name"], self.sliderData[i]["min"],
                                 self.sliderData[i]["max"], valinit=self.sliderData[i]["init"],
                                 valstep=self.sliderData[i]["step"])
            self.sliders.append(self.slider)

        for slider in self.sliders:
            slider.on_changed(self.update)
        for checkbox in self.checkboxes:
            checkbox.on_clicked(self.update)

    def update(self):
        self.amplitude = self.sliders[0].val
        self.showWave = self.checkboxes[0].val

    def init(self):
        for line in self.lines:
            line.set_data([], [])
        return self.patches

    def animate(self, i):
        self.y_data[0] = [1] * 512
        self.y_data[1] = [2] * 512
        self.lines[0].set_data(self.x_data, self.y_data[0])
        self.lines[1].set_data(self.x_data, self.y_data[1])

        return self.patches

    def start(self):
        animation.FuncAnimation(self.fig, self.animate, init_func=self.init, frames=600, repeat=True, interval=20, blit=True)
        plt.show()


graph = CollidingWaves(sliderData=sliderDataList, checkboxData=checkboxDataList)
graph.start()

我做错了什么?

这里似乎只有四个问题:

  • update
    以事件作为参数调用。你需要确保它实际上接受了这个论点,即使你没有使用它
  • 该复选框没有
    val
    属性。您可以通过
    获取复选框的状态。获取\u status
  • y_数据
    分配了两个元素。因此,它从一开始就需要有两个元素
  • 动画需要保留在内存中。因此,您可以将其分配给一个变量
总的来说,这将起作用:

Traceback (most recent call last):
  File "C:\Programs\Python37\lib\site-packages\matplotlib\cbook\__init__.py", line 215, in process
    func(*args, **kwargs)
  File "C:\Programs\Python37\lib\site-packages\matplotlib\widgets.py", line 417, in _update
    self.set_val(val)
  File "C:\Programs\Python37\lib\site-packages\matplotlib\widgets.py", line 438, in set_val
    func(val)
TypeError: update() takes 1 positional argument but 2 were given
import matplotlib.gridspec as gridspec
import numpy as np

from matplotlib import animation
from matplotlib import pyplot as plt
from matplotlib.widgets import Slider, CheckButtons

PI = np.pi

sliderDataList = [{'name': 'Left amplitude', 'min': 0.1, 'max': 8.0, 'init': 2, 'step': 0.01}]
checkboxDataList = [{'name': 'Left wave', 'init': True}]


class CollidingWaves:
    def __init__(self, timeFactor=5, x_range=4 * PI, x_offset=0, y_range=4, y_offset=0, sliderData=[],
                 checkboxData=[], tension=1, massDensity=1):
        self.x_range = x_range
        self.x_offset = x_offset
        self.y_range = y_range
        self.y_offset = y_offset
        self.sliderData = sliderData
        self.checkboxData = checkboxData
        self.tension = tension
        self.massDensity = massDensity
        self.timeFactor = timeFactor
        self.showWave = []
        self.amplitude = 0

        self.fig = plt.figure()

        self.mainGrid = gridspec.GridSpec(2, 1)
        self.ax = plt.subplot(self.mainGrid[0, :])
        self.ax.set(xlim=(-self.x_range - self.x_offset, self.x_range - self.x_offset),
                           ylim=(-self.y_range - self.y_offset, self.y_range - self.y_offset))

        self.x_data = np.linspace(-self.x_range - self.x_offset, self.x_range - self.x_offset, 512)
        self.y_data = [[],[]]

        self.lines = [self.ax.plot([], [])[0] for _ in range(2)]
        self.patches = self.lines

        self.controlCell = self.mainGrid[1, :]
        self.controlGrid = gridspec.GridSpecFromSubplotSpec(1, 7, self.controlCell)

        self.checkboxCell = self.controlGrid[0, 0]
        self.checkboxGrid = gridspec.GridSpecFromSubplotSpec(1, 1, self.checkboxCell)
        self.checkboxes = []
        self.checkboxAx = plt.subplot(self.checkboxGrid[0, 0:1])
        self.checkbox = CheckButtons(self.checkboxAx, tuple(x["name"] for x in self.checkboxData),
                                     tuple(x["init"] for x in self.checkboxData))
        self.checkboxes.append(self.checkbox)

        self.sliderCell = self.controlGrid[0, 2:6]
        self.sliderGrid = gridspec.GridSpecFromSubplotSpec(len(self.sliderData), 1, self.sliderCell)
        self.sliders = []
        for i in range(0, len(self.sliderData)):
            self.sliderAx = plt.subplot(self.sliderGrid[i, 0])
            self.slider = Slider(self.sliderAx, self.sliderData[i]["name"], self.sliderData[i]["min"],
                                 self.sliderData[i]["max"], valinit=self.sliderData[i]["init"],
                                 valstep=self.sliderData[i]["step"])
            self.sliders.append(self.slider)

        for slider in self.sliders:
            slider.on_changed(self.update)
        for checkbox in self.checkboxes:
            checkbox.on_clicked(self.update)

    def update(self, event=None):
        self.amplitude = self.sliders[0].val
        self.showWave = self.checkboxes[0].get_status()

    def init(self):
        for line in self.lines:
            line.set_data([], [])
        return self.patches

    def animate(self, i):
        self.y_data[0] = [1] * 512
        self.y_data[1] = [2] * 512
        self.lines[0].set_data(self.x_data, self.y_data[0])
        self.lines[1].set_data(self.x_data, self.y_data[1])

        return self.patches

    def start(self):
        self.ani = animation.FuncAnimation(self.fig, self.animate, init_func=self.init, frames=600, repeat=True, interval=20, blit=True)
        plt.show()


graph = CollidingWaves(sliderData=sliderDataList, checkboxData=checkboxDataList)
graph.start()