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?
Here is my 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() -- http://mail.python.org/mailman/listinfo/python-list