class Mesh(BaseWidget): """Representation of an unstructured mesh.""" _model_name = Unicode('MeshModel').tag(sync=True) auto_orient = CBool(True).tag(sync=True) cells = DataUnion(dtype=np.int32, shape_constraint=shape_constraints(None, 4)).tag(sync=True) points = DataUnion(dtype=np.float32, shape_constraint=shape_constraints(None, 3)).tag(sync=True)
class DataWidget(RegulusWidget): _model_name = Unicode('RegulusData').tag(sync=True) pts_loc = List().tag(sync=True) pts = DataUnion(np.zeros(0)).tag(sync=True) pts_idx = List().tag(sync=True) pts_extent = List().tag(sync=True) attrs = DataUnion(np.zeros(0)).tag(sync=True) attrs_idx = List().tag(sync=True) attrs_extent = List().tag(sync=True) partitions = List().tag(sync=True) measure = Unicode().tag(sync=True) _data = None def __init__(self, data=None): super().__init__() if data is not None: self.data = data @property def data(self): return self._data @data.setter def data(self, regulus): self._data = regulus if regulus is not None: self.measure = regulus.measure self.pts_loc = regulus.pts_loc pts = regulus.pts original_x = pts.original_x self.pts = original_x self.pts_idx = list(pts.x.columns) self.pts_extent = list(zip(original_x.min(), original_x.max())) self.attrs = pts.values.values self.attrs_idx = list(pts.values.columns) self.attrs_extent = list(zip(pts.values.min(), pts.values.max())) self.partitions = [{ 'id': p.id, 'persistence': p.persistence, 'pts_span': p.pts_span, 'minmax_idx': p.minmax_idx, 'max_merge': p.max_merge, 'extrema': p.extrema, 'x': None, 'y': None } for p in regulus.partitions()] else: self.measure = '' self.pts = [] self.attrs = [] self.partitions = []
class ScaledArray(NDArraySource): """A widget that provides a scaled version of the array. The widget will compute the scaled version of the array on the frontend side in order to avoid re-transmission of data when only the scale changes. """ _model_name = Unicode("ScaledArrayModel").tag(sync=True) _model_module = Unicode(module_name).tag(sync=True) _model_module_version = Unicode(module_version).tag(sync=True) data = DataUnion(help="The data to scale.").tag(sync=True, **data_union_serialization) scale = Instance(Scale).tag(sync=True, **widget_serialization) # TODO: Use Enum instead of free-text: output_dtype = Unicode("inherit").tag(sync=True) def __init__(self, data=Undefined, scale=Undefined, **kwargs): super(ScaledArray, self).__init__(data=data, scale=scale, **kwargs) def _get_dtype(self): if self.output_dtype == "inherit": return self.data.dtype return self.output_dtype def _get_shape(self): if isinstance(self.scale, ColorScale): return self.data.shape + (4, ) return self.data.shape
class ArrayColorMap(ColorMap): """Representation of a color lookup table by an array of values.""" _model_name = Unicode('ArrayColorMapModel').tag(sync=True) values = DataUnion(dtype=np.float32, shape_constraint=shape_constraints(None, 3)).tag( sync=True, **data_union_serialization) space = Enum(["rgb", "hsv"], "rgb").tag(sync=True)
class VoxelsIpyDW(Drawable): """ 3D volumetric data. By default, the voxels are a grid inscribed in the -0.5 < x, y, z < 0.5 cube regardless of the passed voxel array shape (aspect ratio etc.). Different grid size, shape and rotation can be obtained using the model_matrix. Attributes: voxels: `array_like`. 3D array of `int` in range (0, 255). 0 means empty voxel, 1 and above refer to consecutive color_map entries. color_map: `array_like`. Flat array of `int` packed RGB colors (0xff0000 is red, 0xff is blue). The color defined at index i is for voxel value (i+1), e.g.: color_map = [0xff, 0x00ff] voxels = [[[ 0, # empty voxel 1, # blue voxel 2 # red voxel ]]] model_matrix: `array_like`. 4x4 model transform matrix. wireframe: `bool`. Whether mesh should display as wireframe. opacity: `float`. Opacity of voxels. outlines: `bool`. Whether mesh should display with outlines. outlines_color: `int`. Packed RGB color of the resulting outlines (0xff0000 is red, 0xff is blue) """ type = Unicode(read_only=True).tag(sync=True) voxels = DataUnion(default_value=[], dtype=np.uint8).tag(sync=True, **data_union_serialization) color_map = Array(dtype=np.uint32).tag(sync=True, **array_serialization) wireframe = Bool().tag(sync=True) outlines = Bool().tag(sync=True) outlines_color = Int(min=0, max=0xffffff).tag(sync=True) click_callback = None opacity = Float(min=EPSILON, max=1.0, default_value=1.0).tag(sync=True) model_matrix = Array(dtype=np.float32).tag(sync=True, **array_serialization) def __init__(self, **kwargs): super(VoxelsIpyDW, self).__init__(**kwargs) self.set_trait('type', 'Voxels') self.on_msg(self._handle_custom_msg) def _handle_custom_msg(self, content, buffers): if content.get('msg_type', '') == 'click_callback': if self.click_callback is not None: self.click_callback(content['coord']['x'], content['coord']['y'], content['coord']['z'])
class segmenter(DOMWidget): """TODO: Add docstring here """ _model_name = Unicode('segmentModel').tag(sync=True) _model_module = Unicode(module_name).tag(sync=True) _model_module_version = Unicode(module_version).tag(sync=True) _view_name = Unicode('segmentView').tag(sync=True) _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) classColor = Color('red').tag(sync=True) erasing = Bool(True).tag(sync=True) # underlying info for labels - this handles the syncing to ts _labels = Bytes(default_value=None, allow_none=True, read_only=True).tag(sync=True, **labels_serialization) # yikes = data = DataUnion( np.zeros([10, 10, 4], dtype=np.uint8), dtype='uint8', shape_constraint=shape_constraints(None, None, 4), # 2D RGBA ).tag(sync=True, **data_union_serialization) def __init__(self, **kwargs): super().__init__(**kwargs) self.on_msg(self.handle_msg) width = CInt(700).tag(sync=True) height = CInt(700).tag(sync=True) def set_image(self, arr): """ Set the image to be segmented arr : numpy array Shape (WxHx1) or (WxHx3) TODO: transparency here? I removed the transparency enabling code on the typescript side to make things simpler with the class canvas """ image_metadata, image_buffer = binary_image(arr) command = {'name': 'image', 'metadata': image_metadata} self.send(command, (image_buffer, )) def gogogo(self): command = {'name': 'gogogo'} self.send(command, []) def beep(self): command = {'name': 'beep'} self.send(command, []) def gimme(self): command = {'name': 'gimme'} self.send(command, []) def handle_msg(self, widget, content, buffers): # print('widget:', widget) # print(content) # self.gogogo() self.yikes(content['start'])
class IndicatorField(BaseWidget): """Representation of a set of nominal indicator values for each mesh entity.""" _model_name = Unicode('IndicatorFieldModel').tag(sync=True) mesh = Instance(Mesh, allow_none=False).tag(sync=True, **widget_serialization) values = DataUnion(dtype=np.int32, shape_constraint=shape_constraints(None)).tag( sync=True, **data_union_serialization) space = Enum(indicator_field_types, "I3").tag(sync=True)
class Field(BaseWidget): """Representation of a discrete scalar field over a mesh.""" _model_name = Unicode('FieldModel').tag(sync=True) mesh = Instance(Mesh, allow_none=False).tag(sync=True, **widget_serialization) values = DataUnion(dtype=np.float32, shape_constraint=shape_constraints(None)).tag( sync=True, **data_union_serialization) space = Enum(field_types, "P1").tag(sync=True)
class DataArray(VtkWidget): """TODO: Add docstring here """ _model_name = Unicode('DataArrayModel').tag(sync=True) name = Unicode(None, allow_none=True).tag(sync=True) data = DataUnion().tag(sync=True, **data_union_serialization) def __init__(self, data, name=None, **kwargs): super(DataArray, self).__init__(data=data, name=name, **kwargs)
class ImageCanvas(ipywidgets.DOMWidget): """An example widget.""" _view_name = traitlets.Unicode('ImageCanvasView').tag(sync=True) _model_name = traitlets.Unicode('ImageCanvasModel').tag(sync=True) _view_module = traitlets.Unicode('@data-exp-lab/yt-jscanvas').tag(sync=True) _model_module = traitlets.Unicode('@data-exp-lab/yt-jscanvas').tag(sync=True) _view_module_version = traitlets.Unicode('^0.1.8').tag(sync=True) _model_module_version = traitlets.Unicode('^0.1.8').tag(sync=True) image_array = DataUnion(dtype=np.uint8, shape_constraint=rgba_image_shape).tag(sync=True, **data_union_serialization) width = traitlets.Int(256).tag(sync=True) height = traitlets.Int(256).tag(sync=True)
class ArrayColorScale(SequentialScale, ColorScale): """A sequential color scale with array domain/range. """ _model_name = Unicode("ArrayColorScaleModel").tag(sync=True) def __init__(self, colors=Undefined, space="rgb", gamma=1.0, **kwargs): if colors is not Undefined: kwargs["colors"] = colors super(ArrayColorScale, self).__init__(space=space, gamma=gamma, **kwargs) colors = DataUnion( [[0, 0, 0], [1, 1, 1]], # [black, white] shape_constraint=color_array_minlen_validator(2), help="An array of RGB(A) or HSL(A) values, normalized between 0 and 1.", ).tag(sync=True, **data_union_serialization) space = Enum(["rgb", "hsl"], "rgb", help="The color space of the range.").tag(sync=True) gamma = CFloat( 1.0, help="Gamma to use if interpolating in RGB space.").tag(sync=True)
class FRBViewer(ipywidgets.DOMWidget): """Viewing a fixed resolution buffer""" _view_name = traitlets.Unicode('FRBView').tag(sync=True) _model_name = traitlets.Unicode('FRBModel').tag(sync=True) _view_module = traitlets.Unicode('@data-exp-lab/yt-jscanvas').tag(sync=True) _model_module = traitlets.Unicode('@data-exp-lab/yt-jscanvas').tag(sync=True) _view_module_version = traitlets.Unicode('^0.1.8').tag(sync=True) _model_module_version = traitlets.Unicode('^0.1.8').tag(sync=True) width = traitlets.Int(512).tag(sync=True) height = traitlets.Int(512).tag(sync=True) px = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) py = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) pdx = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) pdy = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) val = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) colormaps = traitlets.Instance(ColorMaps).tag(sync = True, **widget_serialization) view_center = traitlets.Tuple((0.5, 0.5)).tag(sync=True, config=True) view_width = traitlets.Tuple((0.2, 0.2)).tag(sync=True, config=True) @traitlets.default('layout') def _layout_default(self): return ipywidgets.Layout(width = '{}px'.format(self.width), height ='{}px'.format(self.height)) @traitlets.default('colormaps') def _colormap_load(self): return ColorMaps() def setup_controls(self): down = ipywidgets.Button(icon="arrow-down", layout=ipywidgets.Layout(width='40px')) up = ipywidgets.Button(icon="arrow-up", layout=ipywidgets.Layout(width='40px')) right = ipywidgets.Button(icon="arrow-right", layout=ipywidgets.Layout(width='40px') ) left = ipywidgets.Button(icon="arrow-left", layout=ipywidgets.Layout(width='40px') ) zoom_start = 1./(self.view_width[0]) zoom = ipywidgets.FloatSlider(min=0.1, max=10, step=0.1, value=zoom_start, description="Zoom") is_log = ipywidgets.Checkbox(value=False, description="Log colorscale") colormaps = ipywidgets.Dropdown( options=list(self.colormaps.cmaps.keys()), description="colormap", value = "viridis") min_val = ipywidgets.BoundedFloatText(description="lower colorbar bound:", value=self.val.min(), min=self.val.min(), max=self.val.max()) max_val = ipywidgets.BoundedFloatText(description="upper colorbar bound:", value=self.val.max(), min=self.val.min(), max=self.val.max()) minmax = ipywidgets.FloatRangeSlider(min=self.val.min(), max=self.val.max()) down.on_click(self.on_ydownclick) up.on_click(self.on_yupclick) right.on_click(self.on_xrightclick) left.on_click(self.on_xleftclick) zoom.observe(self.on_zoom, names='value') # These can be jslinked, so we will do so. ipywidgets.jslink((is_log, 'value'), (self.colormaps, 'is_log')) ipywidgets.jslink((min_val, 'value'), (self.colormaps, 'min_val')) ipywidgets.jslink((max_val, 'value'), (self.colormaps, 'max_val')) # This one seemingly cannot be. ipywidgets.link((colormaps, 'value'), (self.colormaps, 'map_name')) sides = ipywidgets.HBox([left,right], layout=ipywidgets.Layout(justify_content='space-between', width='122px')) nav_buttons = ipywidgets.VBox([up, sides, down], layout=ipywidgets.Layout( align_items='center', width='150px')) all_navigation = ipywidgets.VBox([nav_buttons, zoom], layout=ipywidgets.Layout(align_items='center') ) all_normalizers = ipywidgets.VBox([is_log, colormaps, min_val, max_val], layout=ipywidgets.Layout(align_items='center') ) accordion = ipywidgets.Accordion(children=[all_navigation, all_normalizers]) accordion.set_title(0, 'navigation') accordion.set_title(1, 'colormap controls') return accordion def on_xrightclick(self, b): vc = self.view_center self.view_center = ((vc[0]+0.01),vc[1]) def on_xleftclick(self, b): vc = self.view_center self.view_center = ((vc[0]-0.01),vc[1]) def on_yupclick(self, b): vc = self.view_center self.view_center = (vc[0],(vc[1]+0.01)) def on_ydownclick(self, b): vc = self.view_center self.view_center = (vc[0],(vc[1]-0.01)) def on_zoom(self, change): vw = self.view_width width_x = 1.0/change["new"] ratio = width_x/vw[0] width_y = vw[1]*ratio self.view_width = (width_x, width_y)
class Scatterplot(DataWidget, widgets.DOMWidget): # type: ignore """Progressivis Scatterplot widget.""" # Name of the widget view class in front-end _view_name = Unicode("ScatterplotView").tag(sync=True) # Name of the widget model class in front-end _model_name = Unicode("ScatterplotModel").tag(sync=True) # Name of the front-end module containing widget view _view_module = Unicode("progressivis-nb-widgets").tag(sync=True) # Name of the front-end module containing widget model _model_module = Unicode("progressivis-nb-widgets").tag(sync=True) # Version of the front-end module containing widget view _view_module_version = Unicode("^0.1.0").tag(sync=True) # Version of the front-end module containing widget model _model_module_version = Unicode("^0.1.0").tag(sync=True) hists = DataUnion([], dtype="int32").tag(sync=True, **_serialization) samples = DataUnion(np.zeros((0, 0, 0), dtype="float32"), dtype="float32").tag(sync=True, **_serialization) data = Unicode("{}").tag(sync=True) value = Any("{}").tag(sync=True) move_point = Any("{}").tag(sync=True) modal = Bool(False).tag(sync=True) to_hide = Any("[]").tag(sync=True) def link_module( self, module: MCScatterPlot, refresh: bool = True ) -> None: # -> List[Coroutine[Any, Any, None]]: def _feed_widget(wg: WidgetType, m: MCScatterPlot) -> None: val = m.to_json() data_ = { k: v for (k, v) in val.items() if k not in ("hist_tensor", "sample_tensor") } ht = val.get("hist_tensor", None) if ht is not None: wg.hists = ht st = val.get("sample_tensor", None) if st is not None: wg.samples = st wg.data = JS.dumps(data_) async def _after_run(m: Module, run_number: int) -> None: # pylint: disable=unused-argument if not self.modal: await asynchronize(_feed_widget, self, m) module.on_after_run(_after_run) def from_input_value(_val: Any) -> None: bounds = self.value async def _cbk(): await module.min_value.from_input(bounds["min"]) await module.max_value.from_input(bounds["max"]) aio.create_task(_cbk()) self.observe(from_input_value, "value") # def from_input_move_point(_val: Any) -> None: # aio.create_task(module.move_point.from_input(self.move_point)) # self.observe(from_input_move_point, "move_point") def awake(_val: Any) -> None: if module._json_cache is None or self.modal: return dummy = module._json_cache.get("dummy", 555) module._json_cache["dummy"] = -dummy aio.create_task(asynchronize(_feed_widget, self, module)) # TODO: improve self.observe(awake, "modal") def __init__(self, *, disable: Sequence[Any] = tuple()): super().__init__() self.to_hide = list(disable)
class ArrayScalarMap(ScalarMap): """Representation of a scalar lookup table by an array of values.""" _model_name = Unicode('ArrayScalarMapModel').tag(sync=True) values = DataUnion(dtype=np.float32, shape_constraint=shape_constraints(None)).tag( sync=True, **data_union_serialization)
class FRBViewer(ipywidgets.DOMWidget): """View of a fixed resolution buffer. FRBViewer(width, height, px, py, pdx, pdy, val) This widget creates a view of a fixed resolution buffer of size (`width`, `height`) given data variables `px`, `py`, `pdx`, `pdy`, and val. Updates on the view of the fixed reolution buffer can be made by modifying traitlets `view_center`, `view_width`, or `Colormaps` Parameters ---------- width : integer The width of the fixed resolution buffer output, in pixels height : integer The height of the fixed resolution buffer, in pixels px : array of floats x coordinates for the center of each grid box py : array of floats y coordinates for the center of each grid box pdx : array of floats Values of the half-widths for each grid box pdy : array of floats Values of the half-heights for each grid box val : array of floats Data values for each grid box The data values to be visualized in the fixed resolution buffer. colormaps : :class: `widgyts.Colormaps` This is the widgyt that controls traitlets associated with the colormap. view_center : tuple This is a length two tuple that represents the normalized center of the resulting FRBView. view_width : tuple This is a length two tuple that represents the height and with of the view, normalized to the original size of the image. (0.5, 0.5) represents a view of half the total data with and half the total data height. Examples -------- To create a fixed resolution buffer view of a density field with this widget, and then to display it: >>> ds = yt.load("IsolatedGalaxy") >>> proj = ds.proj("density", "z") >>> frb1 = widgyts.FRBViewer(height=512, width=512, px=proj["px"], ... py=proj["py"], pdx=proj["pdx"], ... pdy=proj["pdy"], val = proj["density"]) >>> display(frb1) """ _view_name = traitlets.Unicode('FRBView').tag(sync=True) _model_name = traitlets.Unicode('FRBModel').tag(sync=True) _view_module = traitlets.Unicode('@data-exp-lab/yt-widgets').tag(sync=True) _model_module = traitlets.Unicode('@data-exp-lab/yt-widgets').tag(sync=True) _view_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) _model_module_version = traitlets.Unicode(EXTENSION_VERSION).tag(sync=True) width = traitlets.Int(512).tag(sync=True) height = traitlets.Int(512).tag(sync=True) px = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) py = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) pdx = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) pdy = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) val = DataUnion(dtype=np.float64, shape_constraint=vmesh_shape).tag(sync = True, **data_union_serialization) colormaps = traitlets.Instance(ColorMaps).tag(sync = True, **widget_serialization) view_center = traitlets.Tuple((0.5, 0.5)).tag(sync=True, config=True) view_width = traitlets.Tuple((0.2, 0.2)).tag(sync=True, config=True) @traitlets.default('layout') def _layout_default(self): return ipywidgets.Layout(width = '{}px'.format(self.width), height ='{}px'.format(self.height)) @traitlets.default('colormaps') def _colormap_load(self): return ColorMaps() def setup_controls(self): down = ipywidgets.Button(icon="arrow-down", layout=ipywidgets.Layout(width='auto', grid_area="down")) up = ipywidgets.Button(icon="arrow-up", layout=ipywidgets.Layout(width='auto', grid_area="up")) right = ipywidgets.Button(icon="arrow-right", layout=ipywidgets.Layout(width='auto', grid_area="right")) left = ipywidgets.Button(icon="arrow-left", layout=ipywidgets.Layout(width='auto', grid_area="left")) zoom_start = 1./(self.view_width[0]) # By setting the dynamic range to be the ratio between coarsest and # finest, we ensure that at the fullest zoom, our smallest point will # be the size of our biggest point at the outermost zoom. dynamic_range = (max(self.pdx.max(), self.pdy.max()) / min(self.pdx.min(), self.pdy.min())) zoom = ipywidgets.FloatSlider(min=0.5, max=dynamic_range, step=0.1, value=zoom_start, description="Zoom", layout=ipywidgets.Layout(width="auto", grid_area="zoom")) is_log = ipywidgets.Checkbox(value=False, description="Log colorscale") colormaps = ipywidgets.Dropdown( options=list(self.colormaps.cmaps.keys()), description="colormap", value = "viridis") min_val = ipywidgets.BoundedFloatText(description="lower colorbar bound:", value=self.val.min(), min=self.val.min(), max=self.val.max()) max_val = ipywidgets.BoundedFloatText(description="upper colorbar bound:", value=self.val.max(), min=self.val.min(), max=self.val.max()) minmax = ipywidgets.FloatRangeSlider(min=self.val.min(), max=self.val.max()) down.on_click(self.on_ydownclick) up.on_click(self.on_yupclick) right.on_click(self.on_xrightclick) left.on_click(self.on_xleftclick) zoom.observe(self.on_zoom, names='value') # These can be jslinked, so we will do so. ipywidgets.jslink((is_log, 'value'), (self.colormaps, 'is_log')) ipywidgets.jslink((min_val, 'value'), (self.colormaps, 'min_val')) ipywidgets.jslink((max_val, 'value'), (self.colormaps, 'max_val')) # This one seemingly cannot be. ipywidgets.link((colormaps, 'value'), (self.colormaps, 'map_name')) nav_buttons = ipywidgets.GridBox(children = [up, left, right, down], layout=ipywidgets.Layout(width='100%', grid_template_columns = '33% 34% 33%', grid_template_rows = 'auto auto auto', grid_template_areas = ''' " . up . " " left . right " " . down . " ''', grid_area='nav_buttons')) all_navigation = ipywidgets.GridBox(children = [nav_buttons, zoom], layout=ipywidgets.Layout(width="300px", grid_template_columns="25% 50% 25%", grid_template_rows="auto auto", grid_template_areas=''' ". nav_buttons ." "zoom zoom zoom" ''' )) all_normalizers = ipywidgets.GridBox(children = [is_log, colormaps, min_val, max_val], layout=ipywidgets.Layout(width="auto") ) accordion = ipywidgets.Accordion(children=[all_navigation, all_normalizers]) accordion.set_title(0, 'navigation') accordion.set_title(1, 'colormap controls') return accordion def on_xrightclick(self, b): vc = self.view_center self.view_center = ((vc[0]+0.01),vc[1]) def on_xleftclick(self, b): vc = self.view_center self.view_center = ((vc[0]-0.01),vc[1]) def on_yupclick(self, b): vc = self.view_center self.view_center = (vc[0],(vc[1]+0.01)) def on_ydownclick(self, b): vc = self.view_center self.view_center = (vc[0],(vc[1]-0.01)) def on_zoom(self, change): vw = self.view_width width_x = 1.0/change["new"] ratio = width_x/vw[0] width_y = vw[1]*ratio self.view_width = (width_x, width_y)