55In the future, will add optional segmentation mesh overlay.
66"""
77
8- from . import cm
98import colorcet
109import matplotlib
1110import collections
1716import ipywidgets as widgets
1817from traitlets import CBool , CFloat , CInt , Unicode , CaselessStrEnum , List , validate , TraitError , Tuple
1918from ipydatawidgets import NDArray , array_serialization , shape_constraints
20- from .trait_types import ITKImage , ImagePointTrait , ImagePoint , PointSetList , PolyDataList , itkimage_serialization , image_point_serialization , polydata_list_serialization , Colormap
19+ from .trait_types import ITKImage , ImagePointTrait , ImagePoint , PointSetList , PolyDataList , itkimage_serialization , image_point_serialization , polydata_list_serialization , Colormap , LookupTable
2120
2221try :
2322 import ipywebrtc
@@ -167,6 +166,12 @@ class Viewer(ViewerParent):
167166 help = "RGB triples from 0.0 to 1.0 that define a custom linear, sequential colormap" )\
168167 .tag (sync = True , ** array_serialization )\
169168 .valid (shape_constraints (None , 3 ))
169+ lut = LookupTable ('glasbey' ,
170+ help = 'Lookup table for the label map.' ).tag (sync = True )
171+ _custom_cmap = NDArray (dtype = np .float32 , default_value = None , allow_none = True ,
172+ help = "RGB triples from 0.0 to 1.0 that define a custom linear, sequential colormap" )\
173+ .tag (sync = True , ** array_serialization )\
174+ .valid (shape_constraints (None , 3 ))
170175 shadow = CBool (
171176 default_value = True ,
172177 help = "Use shadowing in the volume rendering." ).tag (sync = True )
@@ -267,6 +272,10 @@ class Viewer(ViewerParent):
267272 help = "Opacities for the points sets" )\
268273 .tag (sync = True , ** array_serialization )\
269274 .valid (shape_constraints (None ,))
275+ point_set_sizes = NDArray (dtype = np .uint8 , default_value = np .zeros ((0 ,), dtype = np .uint8 ),
276+ help = "Sizes for the points sets" )\
277+ .tag (sync = True , ** array_serialization )\
278+ .valid (shape_constraints (None ,))
270279 point_set_representations = List (
271280 trait = Unicode (),
272281 default_value = [],
@@ -327,6 +336,10 @@ def __init__(self, **kwargs): # noqa: C901
327336 proposal = {'value' : kwargs ['point_set_opacities' ]}
328337 opacities_array = self ._validate_point_set_opacities (proposal )
329338 kwargs ['point_set_opacities' ] = opacities_array
339+ if 'point_set_sizes' in kwargs :
340+ proposal = {'value' : kwargs ['point_set_sizes' ]}
341+ sizes_array = self ._validate_point_set_sizes (proposal )
342+ kwargs ['point_set_sizes' ] = sizes_array
330343 if 'point_set_representations' in kwargs :
331344 proposal = {'value' : kwargs ['point_set_representations' ]}
332345 representations_list = self ._validate_point_set_representations (
@@ -645,6 +658,21 @@ def _validate_point_set_opacities(self, proposal):
645658 result [:n_values ] = value
646659 return result
647660
661+ @validate ('point_set_sizes' )
662+ def _validate_point_set_sizes (self , proposal ):
663+ value = proposal ['value' ]
664+ n_values = 0
665+ if isinstance (value , float ):
666+ n_values = 1
667+ else :
668+ n_values = len (value )
669+ n_sizes = n_values
670+ if self .point_sets :
671+ n_sizes = len (self .point_sets )
672+ result = 3 * np .ones ((n_sizes ,), dtype = np .uint8 )
673+ result [:n_values ] = value
674+ return result
675+
648676 @validate ('point_set_representations' )
649677 def _validate_point_set_representations (self , proposal ):
650678 value = proposal ['value' ]
@@ -667,6 +695,9 @@ def _on_point_sets_changed(self, change=None):
667695 # Make sure we have a sufficient number of opacities
668696 old_opacities = self .point_set_opacities
669697 self .point_set_opacities = old_opacities [:len (self .point_sets )]
698+ # Make sure we have a sufficient number of sizes
699+ old_sizes = self .point_set_sizes
700+ self .point_set_sizes = old_sizes [:len (self .point_sets )]
670701 # Make sure we have a sufficient number of representations
671702 old_representations = self .point_set_representations
672703 self .point_set_representations = old_representations [:len (
@@ -752,13 +783,14 @@ def view(image=None, # noqa: C901
752783 label_map_weights = None , # noqa: C901
753784 label_map_blend = 0.5 ,
754785 cmap = None ,
786+ lut = 'glasbey' ,
755787 select_roi = False ,
756788 interpolation = True ,
757789 gradient_opacity = 0.22 , opacity_gaussians = None , channels = None ,
758790 slicing_planes = False , shadow = True , blend_mode = 'composite' ,
759791 point_sets = [],
760- point_set_colors = [], point_set_opacities = [], point_set_representations = [],
761- # point_set_sizes=[],
792+ point_set_colors = [], point_set_opacities = [],
793+ point_set_representations = [], point_set_sizes = [],
762794 geometries = [],
763795 geometry_colors = [], geometry_opacities = [],
764796 ui_collapsed = False , rotate = False , annotations = True , mode = 'v' ,
@@ -843,12 +875,20 @@ def view(image=None, # noqa: C901
843875 Value that maps to the minimum of image colormap. A single value can
844876 be provided or a list for multi-component images.
845877
846- cmap: list of strings
878+ cmap: list of colormaps
847879 default:
848880 - single component: 'viridis', 'grayscale' with a label map,
849881 - two components: 'BkCy', 'BkMa'
850882 - three components: 'BkRd', 'BkGn', 'BkBu'
851- Colormap for each image component. Some valid values available at itkwidgets.cm.*
883+ Colormap for each image component. Some valid values available at
884+ itkwidgets.cm.*
885+ Colormaps can also be Nx3 float NumPy arrays from 0.0 to 1.0 for the
886+ red, green, blue points on the map or a
887+ matplotlib.colors.LinearSegmentedColormap.
888+
889+ lut: lookup table, default: 'glasbey'
890+ Lookup table for the label map. Some valid values available at
891+ itkwidgets.lut.*
852892
853893 select_roi: bool, default: False
854894 Enable an interactive region of interest widget for the image.
@@ -893,13 +933,16 @@ def view(image=None, # noqa: C901
893933 point_sets: point set, or sequence of point sets
894934 The point sets to visualize.
895935
896- point_set_colors: list of RGB colors
897- Colors for the N geometries . See help(matplotlib.colors) for
936+ point_set_colors: list of (r, g, b) colors
937+ Colors for the N points . See help(matplotlib.colors) for
898938 specification. Defaults to the Glasbey series of categorical colors.
899939
900- point_set_opacities: list of floats, default: [0.5,]*n
940+ point_set_opacities: array of floats, default: [0.5,]*n
901941 Opacity for the point sets, in the range (0.0, 1.0].
902942
943+ point_set_sizes: array of unsigned integers, default: [3,]*n
944+ Sizes for the point sets, in pixel size units.
945+
903946 point_set_representations: list of strings, default: ['points',]*n
904947 How to represent the point set. One of 'hidden', 'points', or 'spheres'.
905948
@@ -1017,6 +1060,7 @@ def view(image=None, # noqa: C901
10171060 label_map_names = label_map_names ,
10181061 label_map_weights = label_map_weights ,
10191062 cmap = cmap ,
1063+ lut = lut ,
10201064 select_roi = select_roi ,
10211065 interpolation = interpolation ,
10221066 gradient_opacity = gradient_opacity , slicing_planes = slicing_planes ,
0 commit comments