Python 我可以同时使用matplotlib中的复选框小部件和动画功能吗?

Python 我可以同时使用matplotlib中的复选框小部件和动画功能吗?,python,matplotlib,animation,widget,Python,Matplotlib,Animation,Widget,我正在尝试创建一个带有复选框的实时绘图,绘图上的每个系列对应一个复选框。我的代码如下。它采用一个df(第一列中的x轴和后续列中的任意数量的y系列,每个系列一列)。您需要一个名为“Temperature.csv”的文件,该文件与脚本位于同一文件夹中,才能正常工作 绘图是实时的(即每xx秒更新一次),但它似乎在每次更新(迭代)时添加了一组新的复选框?据我所知,复选框只被初始化并添加了一次 *编辑以回应欧内斯特的评论 import matplotlib.pyplot as plt from matpl

我正在尝试创建一个带有复选框的实时绘图,绘图上的每个系列对应一个复选框。我的代码如下。它采用一个df(第一列中的x轴和后续列中的任意数量的y系列,每个系列一列)。您需要一个名为“Temperature.csv”的文件,该文件与脚本位于同一文件夹中,才能正常工作

绘图是实时的(即每xx秒更新一次),但它似乎在每次更新(迭代)时添加了一组新的复选框?据我所知,复选框只被初始化并添加了一次

*编辑以回应欧内斯特的评论

import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons
import matplotlib.animation as animation
import pandas as pd
import numpy as np



class TempLogger:
    def __init__(self,name):
        self.name = name
        self.plotFormat()
        self.fp = self.name + '.csv'

    def plotFormat(self):
        self.xLabel = 'Time'
        self.yLabel = 'Temp (°C)'
        self.pltLabel = self.name + ' probe'

    def updateDataFrame(self):
        self.df = pd.read_csv(self.fp)
        self.df_columns = list(self.df)

    def initialisePlot(self):
        self.updateDataFrame()
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(1,1,1)
        self.rax = plt.axes([0.05, 0.4, 0.1, 0.15])
        # now we add checkboxes, one for each series
        self.check = CheckButtons(self.rax, (self.df_columns[1:]), (len(self.df_columns)-1)*[True])
        self.checkButtons_value = (len(self.df_columns)-1)*[True]
        plt.subplots_adjust(left=0.2)

    def updateAnimate(self,i):
        self.updateDataFrame()
        color = ['blue','green','red','cyan','magenta','yellow','black']
        seriesList = []
        self.ax.clear()
        # this plots our series from the dataframe
        for count,col in enumerate(self.df_columns[1:]):
            seriesList.append(self.ax.plot(self.df_columns[0], col,data=self.df, label=col, color = color[count]))
        for count,series in enumerate(seriesList):
            series[0].set_visible(self.checkButtons_value[count])

        def plotList(lists):
            # now we add the functionality to turn check boxes on or off
            def func(label):
                print('clicked on, {}'.format(label))
                for count,series in enumerate(lists):
                    if label == self.df_columns[1:][count]:
                        series[0].set_visible(not series[0].get_visible())
                        self.checkButtons_value[count] = series[0].get_visible()
                        print(self.checkButtons_value[count])
                plt.draw()
            self.check.on_clicked(func)
            plt.show()
            print('leaving "clicked on"')
        plotList(seriesList)
        print('i have left the function')

    def animate(self):
        self.anim = animation.FuncAnimation(self.fig, self.updateAnimate,
                               frames=4, interval=10000, blit=False)
        plt.show()



Temperatures =  TempLogger('Temperatures')
Temperatures.initialisePlot()
Temperatures.animate()
print('try')

根据欧内斯特的评论,问题在于将轴等放在动画函数中。我绑定了多个点击事件。代码正在工作

###############################################################################
###
### FUNCTION: Live plot data from a csv file
### INPUTS: xxx
###
###############################################################################

import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons
import matplotlib.animation as animation
import pandas as pd
import numpy as np



class TempLogger:
    def __init__(self,name):
        self.name = name
        self.plotFormat()
        self.fp = self.name + '.csv'
        self.count = 0

    def plotFormat(self):
        self.xLabel = 'Time'
        self.yLabel = 'Temp (°C)'
        self.pltLabel = self.name + ' probe'

    def updateDataFrame(self):
        self.df = pd.read_csv(self.fp)
        self.df_columns = list(self.df)

    def initialisePlot(self):
        self.updateDataFrame()
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(1,1,1)
        self.rax = plt.axes([0.05, 0.4, 0.1, 0.15])
        # now we add checkboxes, one for each series
        self.check = CheckButtons(self.rax, (self.df_columns[1:]), (len(self.df_columns)-1)*[True])
        self.checkButtons_value = (len(self.df_columns)-1)*[True]
        plt.subplots_adjust(left=0.2)

    def updateAnimate(self,i):
        self.updateDataFrame()
        color = ['blue','green','red','cyan','magenta','yellow','black']
        seriesList = []
        self.ax.clear()

        # this plots our series from the dataframe
        for count,col in enumerate(self.df_columns[1:]):
            seriesList.append(self.ax.plot(self.df_columns[0], col,data=self.df, label=col, color = color[count]))
        for count,series in enumerate(seriesList):
            series[0].set_visible(self.checkButtons_value[count])

        def plotList(lists):
            # now we add the functionality to turn check boxes on or off
            def func(label):
                print('clicked on, {}'.format(label))
                for count,series in enumerate(lists):
                    if label == self.df_columns[1:][count]:
                        series[0].set_visible(not series[0].get_visible())
                        self.checkButtons_value[count] = series[0].get_visible()
                        print(self.checkButtons_value[count])
                plt.draw()
            self.check.on_clicked(func)
            plt.show()
            print('leaving "clicked on"')
        if self.count < 1:
            plotList(seriesList)
            print(self.count)
            self.count += 1
        print('i have left the function')

    def animate(self):
        self.anim = animation.FuncAnimation(self.fig, self.updateAnimate,
                               frames=4, interval=10000, blit=False)
        plt.show()



Temperatures =  TempLogger('Temperatures')
Temperatures.initialisePlot()
Temperatures.animate()
print('try')
###############################################################################
###
###功能:来自csv文件的实时打印数据
###输入:xxx
###
###############################################################################
将matplotlib.pyplot作为plt导入
从matplotlib.widgets导入复选按钮
将matplotlib.animation导入为动画
作为pd进口熊猫
将numpy作为np导入
类模板记录器:
定义初始化(self,name):
self.name=名称
self.plotFormat()
self.fp=self.name+'.csv'
self.count=0
def打印格式(自身):
self.xLabel='Time'
self.yLabel='温度(°C)'
self.pltLabel=self.name+'probe'
def updateDataFrame(自):
self.df=pd.read\u csv(self.fp)
self.df_columns=list(self.df)
def initialisePlot(自):
self.updateDataFrame()
self.fig=plt.figure()
self.ax=self.fig.add_子批次(1,1,1)
self.rax=plt.轴([0.05,0.4,0.1,0.15])
#现在我们添加复选框,每个系列对应一个复选框
self.check=检查按钮(self.rax,(self.df_列[1:]),(len(self.df_列)-1)*[True])
self.checkButtons_值=(len(self.df_列)-1)*[True]
plt.子批次调整(左=0.2)
def updateAnimate(自我,i):
self.updateDataFrame()
颜色=[‘蓝色’、‘绿色’、‘红色’、‘青色’、‘洋红’、‘黄色’、‘黑色’]
序列列表=[]
self.ax.clear()
#这将从数据帧绘制我们的系列
对于计数,枚举中的列(self.df_列[1:]):
seriesList.append(self.ax.plot(self.df_columns[0],col,data=self.df,label=col,color=color[count]))
对于计数,枚举中的系列(系列列表):
系列[0]。设置\u可见(self.checkButtons\u值[count])
def打印列表(列表):
#现在,我们添加了打开或关闭复选框的功能
def func(标签):
打印('单击,{}'。格式(标签))
对于计数,枚举中的系列(列表):
如果label==self.df_列[1:][count]:
系列[0]。设置\u可见(不是系列[0]。获取\u可见()
self.checkButtons_值[count]=系列[0]。获取_可见()
打印(self.checkButtons\u值[计数])
plt.draw()
单击时自行检查(func)
plt.show()
打印('离开“点击”')
如果self.count小于1:
绘图列表(系列列表)
打印(自计数)
self.count+=1
打印('我已离开函数')
def动画(自):
self.anim=animation.FuncAnimation(self.fig、self.updateAnimate、,
帧=4,间隔=10000,blit=False)
plt.show()
温度=模板记录器(“温度”)
温度。initialisePlot()
温度。设置动画()
打印('try')

您需要在动画功能之外创建轴和复选框;否则,在动画中,复选框和轴的数量与帧的数量一样多,比如一分钟后12个,十分钟后120个等等。