spacetelescope / jdaviz

JWST astronomical data analysis tools in the Jupyter platform
https://jdaviz.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
142 stars 74 forks source link

Imviz: error loading a new image when the compass plugin is open #1730

Open Jdaviz-Triage-Bot opened 2 years ago

Jdaviz-Triage-Bot commented 2 years ago

Reporter: Camilla Pacifici

I was in the standalone app, but same error shows in notebook.

This is the first of a set of errors:

---------------------------------------------------------------------------
TraitError                                Traceback (most recent call last)
File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/bqplot_image_gl/viewlistener.py:30, in ViewListener._on_custom_msg(self, widget, content, buffers)
     28     id = content['id']
     29     data = content['data']
---> 30     self.view_data = {**self.view_data, id: data}
     31 elif content.get('event', '') == 'remove_view_data':
     32     id = content['id']

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:715, in TraitType.__set__(self, obj, value)
    713     raise TraitError('The "%s" trait is read-only.' % self.name)
    714 else:
--> 715     self.set(obj, value)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:704, in TraitType.set(self, obj, value)
    700     silent = False
    701 if silent is not True:
    702     # we explicitly compare silent to True just in case the equality
    703     # comparison above returns something other than True/False
--> 704     obj._notify_trait(self.name, old_value, new_value)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:1374, in HasTraits._notify_trait(self, name, old_value, new_value)
   1373 def _notify_trait(self, name, old_value, new_value):
-> 1374     self.notify_change(
   1375         Bunch(
   1376             name=name,
   1377             old=old_value,
   1378             new=new_value,
   1379             owner=self,
   1380             type="change",
   1381         )
   1382     )

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:686, in Widget.notify_change(self, change)
    683     if name in self.keys and self._should_send_property(name, getattr(self, name)):
    684         # Send new state to front-end
    685         self.send_state(key=name)
--> 686 super(Widget, self).notify_change(change)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:1386, in HasTraits.notify_change(self, change)
   1384 def notify_change(self, change):
   1385     """Notify observers of a change event"""
-> 1386     return self._notify_observers(change)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:1431, in HasTraits._notify_observers(self, event)
   1428 elif isinstance(c, EventHandler) and c.name is not None:
   1429     c = getattr(self, c.name)
-> 1431 c(event)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/glue_jupyter/bqplot/image/viewer.py:70, in BqplotImageView._on_view_change(self, *args)
     68 else:
     69     self.shape = None
---> 70 self._sync_figure_aspect()

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/glue_jupyter/bqplot/image/viewer.py:82, in BqplotImageView._sync_figure_aspect(self, *args, **kwargs)
     80 else:
     81     axes_ratio = None
---> 82 self.state._set_axes_aspect_ratio(axes_ratio)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/glue/viewers/matplotlib/state.py:159, in MatplotlibDataViewerState._set_axes_aspect_ratio(self, value)
    152 """
    153 Set the aspect ratio of the axes in which the visualization is shown.
    154 This is a private method that is intended only for internal use, and it
    155 allows this viewer state class to adjust the limits accordingly when
    156 the aspect callback property is set to 'equal'
    157 """
    158 self._axes_aspect_ratio = value
--> 159 self._adjust_limits_aspect(aspect_adjustable='both')

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/glue/utils/decorators.py:32, in avoid_circular.<locals>.wrapper(self, *args, **kwargs)
     30 self._in_avoid_circular = True
     31 try:
---> 32     return meth(self, *args, **kwargs)
     33 finally:
     34     self._in_avoid_circular = False

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/glue/viewers/matplotlib/state.py:231, in MatplotlibDataViewerState._adjust_limits_aspect(self, *args, **kwargs)
    228     y_min = y_mid - y_width / 2.
    229     y_max = y_mid + y_width / 2.
--> 231 with delay_callback(self, 'x_min', 'x_max', 'y_min', 'y_max'):
    232     self.x_min = x_min
    233     self.x_max = x_max

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/echo/core.py:538, in delay_callback.__exit__(self, *args)
    535     self.instance._process_delayed_global_callbacks(resume_props)
    537 for p, args in notifications:
--> 538     p.notify(*args)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/glue/utils/matplotlib.py:176, in defer_draw.<locals>.wrapper(*args, **kwargs)
    172 @wraps(func)
    173 def wrapper(*args, **kwargs):
    175     if len(DEFER_DRAW_BACKENDS) == 0:
--> 176         return func(*args, **kwargs)
    178     # Don't recursively defer draws. We just check the first draw_idle
    179     # method since all should be modified in sync.
    180     if isinstance(DEFER_DRAW_BACKENDS[0].draw_idle, DeferredMethod):

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/glue/viewers/matplotlib/state.py:24, in DeferredDrawCallbackProperty.notify(self, *args, **kwargs)
     22 @defer_draw
     23 def notify(self, *args, **kwargs):
---> 24     super(DeferredDrawCallbackProperty, self).notify(*args, **kwargs)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/echo/core.py:125, in CallbackProperty.notify(self, instance, old, new)
    123     return
    124 for cback in self._callbacks.get(instance, []):
--> 125     cback(new)
    126 for cback in self._2arg_callbacks.get(instance, []):
    127     cback(old, new)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/jdaviz/configs/imviz/plugins/viewers.py:232, in ImvizImageView.on_limits_change(self, *args)
    230         self.compass.clear_compass()
    231     return
--> 232 self.set_compass(self.state.layers[i].layer)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/jdaviz/configs/imviz/plugins/viewers.py:292, in ImvizImageView.set_compass(self, image)
    290 vmin, vmax = PercentileInterval(95).get_limits(arr)
    291 norm = ImageNormalize(vmin=vmin, vmax=vmax, stretch=LinearStretch())
--> 292 self.compass.draw_compass(image.label, wcs_utils.draw_compass_mpl(
    293     arr, orig_shape=image.shape, wcs=image.coords, show=False, zoom_limits=zoom_limits,
    294     norm=norm))

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/jdaviz/configs/imviz/plugins/compass/compass.py:74, in Compass.draw_compass(self, data_label, img_data)
     69 def draw_compass(self, data_label, img_data):
     70     """Draw compass in the plugin.
     71     Input is rendered buffer from Matplotlib.
     72 
     73     """
---> 74     self.icon = self.app.state.layer_icons.get(data_label)
     75     self.data_label = data_label
     76     self.img_data = img_data

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:715, in TraitType.__set__(self, obj, value)
    713     raise TraitError('The "%s" trait is read-only.' % self.name)
    714 else:
--> 715     self.set(obj, value)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:689, in TraitType.set(self, obj, value)
    688 def set(self, obj, value):
--> 689     new_value = self._validate(obj, value)
    690     try:
    691         old_value = obj._trait_values[self.name]

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:721, in TraitType._validate(self, obj, value)
    719     return value
    720 if hasattr(self, "validate"):
--> 721     value = self.validate(obj, value)  # type:ignore[attr-defined]
    722 if obj._cross_validation_lock is False:
    723     value = self._cross_validate(obj, value)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:2400, in Unicode.validate(self, obj, value)
   2398         msg = "Could not decode {!r} for unicode trait '{}' of {} instance."
   2399         raise TraitError(msg.format(value, self.name, class_of(obj)))
-> 2400 self.error(obj, value)

File ~/opt/miniconda3/envs/pr1726/lib/python3.10/site-packages/traitlets/traitlets.py:827, in TraitType.error(self, obj, value, error, info)
    821 else:
    822     e = "The '{}' trait expected {}, not {}.".format(
    823         self.name,
    824         self.info(),
    825         describe("the", value),
    826     )
--> 827 raise TraitError(e)

TraitError: The 'icon' trait of a Compass instance expected a unicode string, not the NoneType None.

🐱


DISCLAIMER: This issue was autocreated by the Jdaviz Issue Creation Bot on behalf of the reporter. If any information is incorrect, please contact Duy Nguyen

pllim commented 2 years ago

I think it somehow triggers the icon update too early.

rosteen commented 2 years ago

@pllim Can this be closed, or was #1731 just a workaround and another better fix is intended?

pllim commented 2 years ago

@kecnry wanted this open for a better solution. #1731 was just a workaround.