I use matplotlib to generate a simple plot with 2 sliders which control a moving point on the plot - showing the user how a change in x or y affects the location of the point. I need these to sliders to share information with one another - if there is a change in one, the other one updates its values based on the changed value (e.g. if the slider that controls x changes, then the slider that controls y is updated, and vice versa).
I've researched this on stackoverflow and tried to implement two solutions (first attempt is commented out in the below code) without success. The last iteration of my attempt seems to work, but after a while it freezes the plot.
My code is:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
# Define x values and y function, y = f(2x**2)
x = np.arange(0.0, 11., 1.)
y = x**2
fxplot, = plt.plot(x, y, lw=2)
#define the bullet point to slide on the function
x0=2.
y0=x0**2
x0_old = x0
y0_old = y0
ptplot, = plt.plot(x0, y0, 'ko')
# Define the sliders
axcolor = 'lightgoldenrodyellow'
ax_x = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor=axcolor)
ax_y = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
xSlider = Slider(ax_x, 'x', 0.0, 10.0, valinit=x0, valstep=1)
ySlider = Slider(ax_y, 'y', 0.0, 10.0**2, valinit=y0, valstep=1)
# Update function; movement of one slider updates the other
# by reinitializing it
def update(val):
global x0_old, y0_old
x0 = xSlider.val
y0 = ySlider.val
# Detect change in y0
if x0 == x0_old:
print('y0 changed',y0,y0_old)
ptplot.set_xdata(np.sqrt(y0))
ptplot.set_ydata(y0)
y0_old = y0
## ax_x.clear()
## xSlider.__init__(ax_x, 'x', 0.0, 10.0, valinit=np.sqrt(y0), valstep=1)
xSlider.valinit = np.sqrt(y0)
xSlider.reset()
# Detect change in x0
if y0 == y0_old:
print('x0 changed',x0,x0_old)
ptplot.set_xdata(x0)
ptplot.set_ydata(x0**2)
x0_old = x0
## ax_y.clear()
## ySlider.__init__(ax_y, 'y', 0.0, 10.0**2, valinit=y0, valstep=1)
ySlider.valinit = x0**2
ySlider.reset()
print('\n')
plt.gcf().canvas.draw_idle()
xSlider.on_changed(update)
ySlider.on_changed(update)
plt.show()
I hope this is a simple fix, but unfortunately, I'm unable to see it and I hoping there is someone out there with more experience using sliders that is able to assist.
Thanks in advance.