diff --git a/jdaviz/configs/imviz/plugins/coords_info/coords_info.py b/jdaviz/configs/imviz/plugins/coords_info/coords_info.py index b90d22a38d..968ea86568 100644 --- a/jdaviz/configs/imviz/plugins/coords_info/coords_info.py +++ b/jdaviz/configs/imviz/plugins/coords_info/coords_info.py @@ -1,7 +1,9 @@ from traitlets import Bool, Unicode +from jdaviz.configs.specviz.plugins.viewers import SpecvizProfileView from jdaviz.core.registries import tool_registry from jdaviz.core.template_mixin import TemplateMixin +from jdaviz.core.marks import PluginScatter __all__ = ['CoordsInfo'] @@ -23,6 +25,29 @@ class CoordsInfo(TemplateMixin): unreliable_world = Bool(False).tag(sync=True) unreliable_pixel = Bool(False).tag(sync=True) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._marks = {} + # initialize marks (this plugin doesn't open so won't create marks on open) + self.marks + + @property + def marks(self): + """ + Access the marks created by this plugin. + """ + if self._marks: + # TODO: replace with cache property? + return self._marks + + # create marks for each of the spectral viewers (will need a listener event to create marks + # for new viewers if dynamic creation of spectral viewers is ever supported) + for id, viewer in self.app._viewer_store.items(): + if isinstance(viewer, SpecvizProfileView): + self._marks[id] = PluginScatter(viewer, visible=False) + viewer.figure.marks = viewer.figure.marks + [self._marks[id]] + return self._marks + def reset_coords_display(self): self.world_label_prefix = '\u00A0' self.world_label_prefix_2 = '\u00A0' diff --git a/jdaviz/configs/specviz/plugins/viewers.py b/jdaviz/configs/specviz/plugins/viewers.py index 92d94e640c..9c8faeef31 100644 --- a/jdaviz/configs/specviz/plugins/viewers.py +++ b/jdaviz/configs/specviz/plugins/viewers.py @@ -118,6 +118,7 @@ def on_mouse_or_key_event(self, data): self.label_mouseover.pixel = "" self.label_mouseover.reset_coords_display() self.label_mouseover.value = "" + self.label_mouseover.marks[self._reference_id].visible = False return fmt = 'x={:0' + str(closest_maxsize) + '.1f}' @@ -130,12 +131,15 @@ def on_mouse_or_key_event(self, data): self.label_mouseover.world_dec_deg = closest_flux.unit.to_string() self.label_mouseover.icon = closest_label self.label_mouseover.value = "" # Not used + self.label_mouseover.marks[self._reference_id].update_xy([closest_wave.value], [closest_flux.value]) + self.label_mouseover.marks[self._reference_id].visible = True elif data['event'] == 'mouseleave' or data['event'] == 'mouseenter': self.label_mouseover.icon = "" self.label_mouseover.pixel = "" self.label_mouseover.reset_coords_display() self.label_mouseover.value = "" + self.label_mouseover.marks[self._reference_id].visible = False def _expected_subset_layer_default(self, layer_state): super()._expected_subset_layer_default(layer_state) diff --git a/jdaviz/core/marks.py b/jdaviz/core/marks.py index 110cc87deb..cdfa05f7d7 100644 --- a/jdaviz/core/marks.py +++ b/jdaviz/core/marks.py @@ -13,7 +13,7 @@ __all__ = ['OffscreenLinesMarks', 'BaseSpectrumVerticalLine', 'SpectralLine', 'SliceIndicatorMarks', 'ShadowMixin', 'ShadowLine', 'ShadowLabelFixedY', - 'PluginLine', + 'PluginLine', 'PluginScatter', 'LineAnalysisContinuum', 'LineAnalysisContinuumCenter', 'LineAnalysisContinuumLeft', 'LineAnalysisContinuumRight', 'LineUncertainties', 'ScatterMask', 'SelectedSpaxel'] @@ -484,19 +484,31 @@ def _on_shadowing_changed(self, change): self._update_align() -class PluginLine(Lines, HubListener): - def __init__(self, viewer, x=[], y=[], **kwargs): - # color is same blue as import button - super().__init__(x=x, y=y, colors=["#007BA1"], scales=viewer.scales, **kwargs) - +class PluginMark(): def update_xy(self, x, y): self.x = np.asarray(x) self.y = np.asarray(y) + def append_xy(self, x, y): + self.x = np.append(self.x, x) + self.y = np.append(self.y, y) + def clear(self): self.update_xy([], []) +class PluginLine(Lines, PluginMark, HubListener): + def __init__(self, viewer, x=[], y=[], **kwargs): + # color is same blue as import button + super().__init__(x=x, y=y, colors=["#007BA1"], scales=viewer.scales, **kwargs) + + +class PluginScatter(Scatter, PluginMark, HubListener): + def __init__(self, viewer, x=[], y=[], **kwargs): + # color is same blue as import button + super().__init__(x=x, y=y, colors=["#007BA1"], scales=viewer.scales, **kwargs) + + class LineAnalysisContinuum(PluginLine): pass