title: Matplotlib Updating slider widget range
body: <p>I am trying to write a small bit of code that interactively deletes selected slices in an image series using matplotlib. I have created a button 'delete' which stores a number of indices to be deleted when the button 'update' is selected. However, I am currently unable to reset the range of my slider widget, i.e. removing the number of deleted slices from valmax. What is the pythonic solution to this problem? </p>
  
  <p>Here is my code:</p>
  
  <pre><code>import dicom
  import numpy as np
  import matplotlib.pyplot as plt
  from matplotlib.widgets import Slider, Button
  
  frame = 0
  #store indices of slices to be deleted
  delete_list = []
  
  
  def main():
  
      data = np.random.rand(16,256,256)
      nframes = data.shape[0]
  
      raw_dicom_stack = []
      for x in range (nframes):
          raw_dicom_stack.append(data[x,:,:])
  
      #yframe = 0
  
      # Visualize it
      viewer = VolumeViewer(raw_dicom_stack, nframes)
      viewer.show()
  
  class VolumeViewer(object):
      def __init__(self, raw_dicom_stack, nframes):
  
          global delete_list
  
          self.raw_dicom_stack = raw_dicom_stack
          self.nframes = nframes
          self.delete_list = delete_list
  
          # Setup the axes.
          self.fig, self.ax = plt.subplots()
          self.slider_ax = self.fig.add_axes([0.2, 0.03, 0.65, 0.03])
          self.delete_ax = self.fig.add_axes([0.85,0.84,0.1,0.04])
          self.update_ax = self.fig.add_axes([0.85,0.78,0.1,0.04])
          self.register_ax = self.fig.add_axes([0.85,0.72,0.1,0.04])
          self.add_ax = self.fig.add_axes([0.85,0.66,0.1,0.04])
  
          # Make the slider
          self.slider = Slider(self.slider_ax, 'Frame', 1, self.nframes, 
                              valinit=1, valfmt='%1d/{}'.format(self.nframes))
          self.slider.on_changed(self.update)
  
          #Make the buttons
          self.del_button = Button(self.delete_ax, 'Delete')
          self.del_button.on_clicked(self.delete)
  
          self.upd_button = Button(self.update_ax, 'Update')
          self.upd_button.on_clicked(self.img_update)
  
          self.reg_button = Button(self.register_ax, 'Register')
  
          self.add_button = Button(self.add_ax, "Add")
  
          # Plot the first slice of the image
          self.im = self.ax.imshow(np.array(raw_dicom_stack[0]))
  
      def update(self, value):
          global frame
          frame = int(np.round(value - 1))
  
          # Update the image data
          dat = np.array(self.raw_dicom_stack[frame])
          self.im.set_data(dat)
  
          # Reset the image scaling bounds (this may not be necessary for you)
          self.im.set_clim([dat.min(), dat.max()])
  
          # Redraw the plot
          self.fig.canvas.draw()
  
      def delete(self,event):
          global frame
          global delete_list
  
          delete_list.append(frame)
          print 'Frame %s has been added to list of slices to be deleted' %str(frame+1)
          print 'Please click update to delete these slices and show updated image series \n'
  
          #Remove duplicates from delete list
  
      def img_update(self,event):
          #function deletes image stacks and updates viewer
          global delete_list
  
          #Remove duplicates from list and sort into numerical order
          delete_list = list(set(delete_list))
          delete_list.sort()
  
          #Make sure delete_list is not empty
          if not delete_list:
              print "Delete list is empty, no slices to delete"
          #Loop through delete list in reverse numerical order and remove slices from series
          else:
              for i in reversed(delete_list):
                  self.raw_dicom_stack.pop(i)
                  print 'Slice %i removed from dicom series \n' %(i+1)
  
          #Can now remove contents from delete_list
          del delete_list[:]
          #Update slider range
          self.nframes =  len(self.raw_dicom_stack)
  
  
      def show(self):
          plt.show()
  
  if __name__ == '__main__':
      main()
  </code></pre>