python-3.xplotbar-chartmatplotlib-widget

How can I remove the axhline I added with my slider widget


I pulled the below code from SO and modified it to get closer to what I need. Basically, I want the user to move a slider to change the position of the axhline, which then will be used to do come calculations. My issue is that the line which should remove the previous axhline does not remove it and it breaks my function and new lines won't be create on slider changes. What is wrong with my remove() call? Is the reference to the axhline getting lost when the function terminates? I tried to make it global, but that didn't help.

    # Import libraries
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
%matplotlib notebook

# Create a subplot
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.35)
r = 0.6
g = 0.2
b = 0.5

# Create and plot a bar chart
year = [2002, 2004, 2006, 2008, 2010]
production = [25, 15, 35, 30, 10]
plt.bar(year, production, color=(r, g, b))
targ_line = plt.axhline(y=20, xmin=-.1, clip_on=False, zorder=1, color='#e82713')

# Create 3 axes for 3 sliders red,green and blue
target = plt.axes([0.25, 0.2, 0.65, 0.03])


# Create a slider from 0.0 to 35.0 in axes target
# with 20.0 as initial value.
red = Slider(target, 'Target', 0.0, 35.0, 20)


# Create fuction to be called when slider value is changed
# This is the part I am having trouble with.  I want to remove the previous line
# so that there will only be one axhline present

def update(val):  
    #targ_line.remove()   # uncommenting this line doesn't remove the line and prevents the remainder of the code in this function from running.
    Y = red.val
    targ_line = ax.axhline(y=Y, color = 'black')
    ax.bar(year, production, color=(r, g, b),
        edgecolor="black")

# Call update function when slider value is changed
red.on_changed(update)


# Create axes for reset button and create button
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color='gold',
                hovercolor='skyblue')

# Create a function resetSlider to set slider to
# initial values when Reset button is clicked

def resetSlider(event):
        red.reset()


# Call resetSlider function when clicked on reset button
button.on_clicked(resetSlider)

# Display graph
plt.show()

Solution

  • You can try updating the axhline instead of recreating it. For example:

    def update(val):  
        #Y = red.val
        #targ_line = ax.axhline(y=Y, color = 'black')
        targ_line.set_ydata(y=red.val)
        targ_line.set_color('black')
        ax.bar(year, production, color=(r, g, b), edgecolor="black")