I'm drawing a simple line (y = mx + b) and I'm rotating it about the origin (only in the first quadrant) and I'm filling the between the line and the x-axis. I change the slope of the line via a slider. I've researched this and it appears that in order to keep the region filled as the line rotates is to use "Collections", which implemented but now I enter an infinite loop. Specifically, as I change the slider, the filled region is correct but only for one change of the slider. After this it enters into an infinite loop. Any help would be appreciated. The primary portion of my code is below:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation
from matplotlib.widgets import Slider # import the Slider widget
fig = plt.figure()
axcolor = 'lightgoldenrodyellow'
main_ax = plt.axes([0, .5, 10, 15])
slider_ax = plt.axes([0.2, 0.08, .7, .03], facecolor=axcolor)
#Some constants
torad = np.pi/180
WAngle = 20.
xmax = 10
#Slider min max
s_min = 00
s_max = 60
s_init = WAngle
# set the current plot to main_ax
plt.sca(main_ax)
#Define and plot the triangle
plt.axes() #Select the main axis
plt.title('test')
plt.xlim(0,10)
plt.ylim(0,10)
#Now define the line, only need the second point, first point 0,0
Beta = WAngle
Bx = 10
By = Bx*np.tan(Beta * torad)
# Draw line and add to plot
xdat = [0, 10]
ydat = [0, By]
line = plt.Line2D(xdat, ydat,color='k') #(x1,x2),(y1,y2)
axis = plt.gca()
axis.add_line(line)
fillbet = plt.fill_between(xdat, ydat, color="#539ecd",label="wedge")
sline = Slider(slider_ax, 'line', s_min, s_max, valinit=s_init)
## def update(val):
def update(val):
myangle = sline.val
By = Bx*np.tan(myangle * torad)
xdat = [0, Bx]
ydat = [0, By]
line.set_xdata((0, Bx))
line.set_ydata((0, By))
for collection in axis.collections:
if str(collection.get_label()) == "wedge":
collection.remove()
del collection
fillbet = plt.fill_between(xdat, ydat, color='#539ecd')
plt.gcf().canvas.draw_idle()
sline.on_changed(update)
plt.axis('scaled')
plt.show()
Your code is mostly working, but you had 2 unfortunate bugs.
update()
function, so that it can be deleted the second time
around.The following code seem to do what you want:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation
from matplotlib.widgets import Slider # import the Slider widget
fig = plt.figure()
axcolor = 'lightgoldenrodyellow'
main_ax = plt.axes([0, .5, 10, 15])
slider_ax = plt.axes([0.2, 0.08, .7, .03], facecolor=axcolor)
#Some constants
torad = np.pi/180
WAngle = 20.
xmax = 10
#Slider min max
s_min = 0
s_max = 60
s_init = WAngle
# set the current plot to main_ax
plt.sca(main_ax)
#Define and plot the triangle
plt.axes() #Select the main axis
plt.title('test')
plt.xlim(0,10)
plt.ylim(0,10)
#Now define the line, only need the second point, first point 0,0
Beta = WAngle
Bx = 10
By = Bx*np.tan(Beta * torad)
# Draw line and add to plot
xdat = [0, 10]
ydat = [0, By]
line = plt.Line2D(xdat, ydat,color='k') #(x1,x2),(y1,y2)
axis = plt.gca()
axis.add_line(line)
fillbet = plt.fill_between(xdat, ydat, color="#539ecd",label="wedge")
sline = Slider(slider_ax, 'line', s_min, s_max, valinit=s_init)
## def update(val):
def update(val):
myangle = sline.val
By = Bx*np.tan(myangle * torad)
xdat = [0, Bx]
ydat = [0, By]
line.set_xdata((0, Bx))
line.set_ydata((0, By))
for collection in axis.collections:
if str(collection.get_label()) == "wedge":
collection.remove()
fillbet = plt.fill_between(xdat, ydat, color='#539ecd', label="wedge")
fig.canvas.draw_idle()
sline.on_changed(update)
plt.axis('scaled')
plt.show()