illumi
illumi

Reputation: 284

Retrieving the selected values from a CheckButtons object in matplotlib

I have two CheckButtons widgets with 3 elements each. I'd like to read the status of both widgets when either one of the CheckButtons is selected then update the chart accordingly.

The slider widget has a .val for returning the status of a slider, but the CheckButtons widget seems a bit more awkward (or am I missing something obvious)?

short example:

import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons

class Example:

    def updateChart(self, event):
        colour = self.colours.labels # gets labes as text object, is there an easy way of getting the status?
        print colour
        # measurement = measurements.something

    def __init__(self):
        colourax = plt.axes([0.5, 0.4, 0.09, 0.2])
        measurementax = plt.axes([0.5, 0.6, 0.09, 0.2])
        self.colours = CheckButtons(colourax, ('Red', 'Green', 'Blue'), (False, False, False))
        self.measurements = CheckButtons(measurementax, ('1', '2', '3'), (False, False, False))
        self.colours.on_clicked(self.updateChart)
        self.measurements.on_clicked(self.updateChart)

    def run(self):
        plt.show()

ex = Example()
ex.run()

Upvotes: 4

Views: 3571

Answers (3)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339120

The current development version (as of July 2017) has a

CheckButtons.get_status()

method incorporated. This can be used to query the current status of the checkboxes. It should be released in the stable version pretty soon. (Source here)

Until then, you may emulate this behaviour by using your own get_status method as in the following. It uses the same mechanism as the get_status() method from the development version, which is also very close to what the answer of @Gruby is proposing (looking at the visibility of the lines).

import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons

class Example:

    def updateChart(self, event):
        colour = self.get_status(self.colours)
        measurement = self.get_status(self.measurements)
        print measurement, colour

    def get_status(self, cb):
        return [l1.get_visible() for (l1, l2) in cb.lines]


    def __init__(self):
        colourax = plt.axes([0.5, 0.4, 0.09, 0.2])
        measurementax = plt.axes([0.5, 0.6, 0.09, 0.2])
        self.colours = CheckButtons(colourax, ('Red', 'Green', 'Blue'), (False, False, False))
        self.measurements = CheckButtons(measurementax, ('1', '2', '3'), (False, False, False))
        self.colours.on_clicked(self.updateChart)
        self.measurements.on_clicked(self.updateChart)

    def run(self):
        plt.show()

ex = Example()
ex.run()

Upvotes: 3

Gruby
Gruby

Reputation: 71

I know it's a bit awkward, but you can check for visibility of on of the cross lines in check boxes.

import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons

colourax = plt.axes([0.5, 0.4, 0.09, 0.2])
colours = CheckButtons(colourax, ('Red', 'Green', 'Blue'), (False, False, False))

isRedChecked = colours.lines[0][0].get_visible()
isGreenChecked = colours.lines[1][0].get_visible()
isBlueChecked = colours.lines[2][0].get_visible()

Upvotes: 7

ali_m
ali_m

Reputation: 74162

There might perhaps be a more elegant way but you can always keep track of the states of each of the checkboxes yourself, e.g. in a dict. The function that you specify using on_clicked() will receive the label string of the active checkbox as its second argument, which you can then use to update the status appropriately:

import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons

class Example:

    def onColor(self,label):
        self.cstates[label] = not self.cstates[label]
        print 'un'*(not self.cstates[label]) + 'checked %s' %label
        self.updateChart()

    def onMeasurement(self,label):
        self.mstates[label] = not self.mstates[label]
        print 'un'*(not self.mstates[label]) + 'checked %s' %label
        self.updateChart()

    def updateChart(self, event=None):
        """do something here using self.cstates and self.mstates?"""
        pass

    def __init__(self):
        colourax = plt.axes([0.5, 0.4, 0.09, 0.2])
        measurementax = plt.axes([0.5, 0.6, 0.09, 0.2])
        clabels, cvals = ('Red', 'Green', 'Blue'), (False,)*3
        mlabels, mvals = ('1', '2', '3'), (False,)*3
        self.cstates = dict(zip(clabels,cvals))
        self.mstates = dict(zip(mlabels,mvals))
        self.colours = CheckButtons(colourax, clabels, cvals)
        self.colours.on_clicked(self.onColor)
        self.measurements = CheckButtons(measurementax, mlabels, mvals)
        self.measurements.on_clicked(self.onMeasurement)

    def run(self):
        plt.show()

ex = Example()
ex.run()

Not the prettiest, but it works!

Upvotes: 1

Related Questions