Update slider widget range


M

moadeep

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()
 
Ad

Advertisements

M

Mark Lawrence

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?

self.nframes = len(self.raw_dicom_stack)

If I've read your intentions correctly the line above should read

self.slider.valmax = len(self.raw_dicom_stack)

If I'm wrong then please ask on the matplotlib users mailing list or
possibly stackoverflow.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top