Могу ли я использовать виджет-флажок и функцию анимации из matplotlib одновременно? - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь создать живой сюжет с флажками, по одному для каждой серии на сюжете. Мой код ниже. Требуется pandas 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')

1 Ответ

0 голосов
/ 03 марта 2020

Согласно комментарию Эрнеста, проблема заключалась в размещении осей и c внутри функции анимации. Я связывал несколько событий клика. Код работает сейчас

###############################################################################
###
### 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...