I made an interactive plot with python using matplotlib and I want to call it by putting it inside a function. Everything works until I put my whole code inside the function make_plot(). Running the code without the make_plot() function gives me exactly what I want. Why is it not working anymore when inside another function (I just lose the interactive functionality)?
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import numpy as np
def make_plot():
def button_clicked(event):
global line_plotted
if line_plotted:
ax1.lines[1].remove()
line_plotted = False
else:
ax1.plot(line[0], line[1], color='r', linestyle='--')
line_plotted = True
fig.canvas.draw()
plt.ion()
x = np.linspace(0, 4*np.pi, 500)
y = np.sin(x)
line = [0, 4 * np.pi], [1, 1]
fig = plt.figure(figsize=(15,5))
ax1 = fig.add_subplot()
ax1.plot(x,y)
ax1.plot(line[0], line[1], color='r', linestyle='--')
line_plotted = True
button_ax = plt.axes([0.8, 0.05, 0.1, 0.075])
button = Button(button_ax, 'Show red line')
button.on_clicked(button_clicked)
plt.show()
make_plot()
I tried putting the button_clicked(event) function outside the make_plot() function but it didn't help.
global line_plotted
-->
nonlocal line_plotted
After you move all code inside a function, line_plotted doesn't live in global level, nonlocal keyword is used to reference a variable in the nearest scope.
Edit: full code
run in pycharm and spyder are all interactive -- click button .
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import numpy as np
matplotlib.use("TkAgg")
def make_plot():
def button_clicked(event):
nonlocal line_plotted
if line_plotted:
ax1.lines[1].remove()
line_plotted = False
else:
ax1.plot(line[0], line[1], color="r", linestyle="--")
line_plotted = True
fig.canvas.draw()
plt.ion()
x = np.linspace(0, 4 * np.pi, 500)
y = np.sin(x)
line = [0, 4 * np.pi], [1, 1]
fig = plt.figure(figsize=(15, 5))
ax1 = fig.add_subplot()
ax1.plot(x, y)
ax1.plot(line[0], line[1], color="r", linestyle="--")
line_plotted = True
button_ax = plt.axes([0.8, 0.05, 0.1, 0.075])
button = Button(button_ax, "Show red line")
button.on_clicked(button_clicked)
plt.show(block=True)
make_plot()