TheFlash
TheFlash

Reputation: 25

matplotlib ( python) - change global varible in click event

matplotlib - change global varible in click event.

Hey I spent too many hours to solve this problem and nothing for now. I tried this code:

def menu_event(event):
    global state
    state +=1
    print(state)

def main():
    ...
    b = Button(button_ax, name, color=color, hovercolor=font_color)
    b.on_clicked(menu_event)
    ...
    while True:
        print(state)
    

state = 0
if __name__ == "__main__":
    main()

and the state varible doesn't change! What I get in the output is the following:

0
0
0
1 # A push of a button happened
0
0
0
2 # A push of a button happened
0
0
0
3 # A push of a button happened
0
0

...

So it makes "state" like static varible of menu_event(event). What do I wrong? Thanks for the help!

Upvotes: 0

Views: 630

Answers (1)

czeni
czeni

Reputation: 446

Matplotlib's doc has a nice example code for defining/using a button interactively.

For the sake of curiosity, I changed the example by making ind, next and prev as global variable and fuctions:

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

freqs = np.arange(2, 20, 3)

fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
t = np.arange(0.0, 1.0, 0.001)
s = np.sin(2*np.pi*freqs[0]*t)
l, = plt.plot(t, s, lw=2)

def next(event):
    global ind
    ind += 1
    i = ind % len(freqs)
    ydata = np.sin(2*np.pi*freqs[i]*t)
    l.set_ydata(ydata)
    plt.draw()

def prev(event):
    global ind
    ind -= 1
    i = ind % len(freqs)
    ydata = np.sin(2*np.pi*freqs[i]*t)
    l.set_ydata(ydata)
    plt.draw()


ind = 0

def main():
    axprev = plt.axes([0.7, 0.05, 0.1, 0.075])
    axnext = plt.axes([0.81, 0.05, 0.1, 0.075])
    bnext = Button(axnext, 'Next')
    bnext.on_clicked(next)
    bprev = Button(axprev, 'Previous')
    bprev.on_clicked(prev)
    plt.show()

if __name__ == "__main__":
    main()

It works like the original code.

So using global variable can be an option, but defining the state variable together with the function that modifies it in a single class is a better approach that you should consider.

For example:


class State(object):

    def __init__(self):
        self._state = 0
        ...

    def click_event(self, event):
        self._state += 1
        ...
        plt.draw()

state = State()
b = Button(button_ax, name, color=color, hovercolor=font_color)
b.on_clicked(state.click_event)

Upvotes: 2

Related Questions