Scaled data widget

ipyscales also allow for front-end based scaling of array data by implementing the ipydatawidgets interfaces. This allows e.g. for sending you (large) dataset once, and then rapidly re-scaling it on the front-end side.

[1]:
import numpy as np
from ipyscales import LinearScale, LogScale
from ipyscales.datawidgets import ScaledArray
from ipydatawidgets import DataImage
np.random.seed(0)
[2]:
from ipyscales._example_helper import use_example_model_ids
use_example_model_ids()

Set up some random RGBA data:

[3]:
data = np.array(255 * np.random.rand(200, 200, 4), dtype='uint8')

Set up two simple scales for translating each channel value, one linear, one logarithmic:

[4]:
linear = LinearScale(range=(0, 255), domain=(0, 255), clamp=True)
# Setup log scale as alternative scale. Note the non-zero domain with clamp!
log = LogScale(range=(0, 255), domain=(1, 255), clamp=True)

Set up our scaled data source. This will not transmit the scaled data back to the kernel, but if passed to a data union trait, the scaled data will be used:

[5]:
scaled_data = ScaledArray(data=data, scale=linear)

Pass the scaled data to a DataImage to visualize it:

[6]:
image = DataImage(data=scaled_data)
image

Add some controls for selecting which scale to use, and what the range of the scales should be:

[7]:
from ipywidgets import FloatRangeSlider, jslink, HBox
from ipyscales.selectors import WidgetDropdown

range_selector = FloatRangeSlider(min=0, max=255, step=1, description='range', readout_format='d')
jslink((linear, 'range'), (range_selector, 'value'))
jslink((range_selector, 'value'), (log, 'range'))

scale_selector = WidgetDropdown(options={'Linear': linear, 'Log': log}, description='Scale')
jslink((scale_selector, 'value'), (scaled_data, 'scale'))

HBox([scale_selector, range_selector])

Color mapped data

Set up a 2D scalar field of floats (0-1) to act as our data. Here, a nice diagonal gradient:

[8]:
side_length = 200
scalar_field = np.sum(np.meshgrid(
    np.linspace(0, 0.5, side_length),
    np.linspace(0, 0.5, side_length),
), axis=0)

This time, we use a color map as the scale. Here we use named, sequential color maps:

[9]:
from ipyscales import NamedSequentialColorMap
cmap = NamedSequentialColorMap(name='viridis')

When setting up a scaled array with a color map, we should specify the output dtype we want. If not, it will inherit the dtype of the input data. In this case, the input dtype is float, and DataImage expects a unsigned 8-bit integer.

[10]:
mapped_data = ScaledArray(data=scalar_field, scale=cmap, output_dtype='uint8')

Visualize the mapped data:

[11]:
mapped_image = DataImage(data=mapped_data)
mapped_image

Show a drop-down selector for the color map name:

[12]:
cmap.edit()