Add min/max controls to the Jupyter image layer control widgets

Now by showing `my_image_layer.controls` you get widgets that let you adjust
the opacity, stretch function, and data range. The best UI I could come up
with for the data range has "coarse" controls that are typed in manually and
"fine" controls that use a range slider widget.

I note that in my testing, the adjustments don't apply until focus changes to
another widget, which makes for a kind of weak UX. I checked the ipywidgets
bug tracker but don't see any complaints about this; I'm not sure what's going
on, since this seems like a pretty basic piece of functionality.
This commit is contained in:
Peter Williams 2019-06-05 14:13:36 -04:00
Родитель af97e29d1d
Коммит ac8b91930a
2 изменённых файлов: 41 добавлений и 3 удалений

Просмотреть файл

@ -118,5 +118,43 @@ class JupyterImageLayer(ImageLayer):
)
link((stretch, 'value'), (self, 'stretch'))
self._controls = widgets.HBox([opacity, stretch])
double_width = widgets.Layout(width='600px')
vrange = widgets.FloatRangeSlider(
description = 'Fine min/max:',
value = [self.vmin, self.vmax],
min = self._data_min,
max = self._data_max,
readout = True,
layout = double_width,
)
# Linkage must be manual since vrange uses a pair of values whereas we
# have two separate traitlets.
vrange.observe(self._vrange_slider_updated, names=['value'])
def update_vrange(change):
# Note: when this function is called, these values are indeed updated.
vrange.value = (self.vmin, self.vmax)
self.observe(update_vrange, names=['vmin', 'vmax'])
coarse_min = widgets.FloatText(
description = 'Coarse min:',
value = self._data_min,
)
link((coarse_min, 'value'), (vrange, 'min'))
coarse_max = widgets.FloatText(
description = 'Coarse max:',
value = self._data_max,
)
link((coarse_max, 'value'), (vrange, 'max'))
self._controls = widgets.VBox([
widgets.HBox([opacity, stretch]),
widgets.HBox([coarse_min, coarse_max]),
vrange,
])
return self._controls
def _vrange_slider_updated(self, change):
self.vmin, self.vmax = change['new']

Просмотреть файл

@ -601,8 +601,8 @@ class ImageLayer(HasTraits):
self._stretch_version = 0
data = fits.getdata(self._sanitized_image)
self.vmin = np.nanpercentile(data, 0.5)
self.vmax = np.nanpercentile(data, 99.5)
self._data_min, self.vmin, self.vmax, self._data_max = \
np.nanpercentile(data, [0, 0.5, 99.5, 100])
self._initialize_layer()