Note

Using interactive maps requires ipyleaflet, an optional dependency. See the guide for installation and troubleshooting instructions.

Interactive

Classes:

WorkflowsLayer(imagery[, scales, colormap, …])

Subclass of ipyleaflet.TileLayer for displaying a Workflows Image or ImageCollection.

LayerController(map, **kwargs)

An ipyleaflet.WidgetControl for managing WorkflowsLayer.

LayerControllerList(map[, …])

Widget displaying a list of LayerControllerRow widgets for a Map.

ImagePickerWidget([map, default_layer, …])

Widget to pick a layer from the map, as an Image.

ImageCollectionPickerWidget([map, …])

Widget to pick a layer from the map, as an ImageCollection.

Map(**kwargs)

Subclass of ipyleaflet.Map with Workflows defaults and extra helper methods.

MapApp([map, layer_controller_list, …])

Widget displaying a map, layers, and output logs in a nicer layout.

ParameterSet(notify_object, notify_name, …)

Parameters for a WorkflowsLayer, which updates the layer when new values are assigned.

ProxytypeInstance([klass, args, kw])

Trait type that tries to promote values to a given Proxytype

PixelInspector(map[, position, layout])

Display pixel values when clicking on the map.

WorkflowsBrowser([map])

Widget displaying a UI for browsing and searching Workflow objects, and displaying them on the map.

Data:

map

A single MapApp instance that all visualize calls are automatically added to.

flows

Browse shared Workflow objects (and add them to the map) with a predefined WorkflowsBrowser instance.

class WorkflowsLayer(imagery, scales=None, colormap=None, checkerboard=None, reduction=None, log_level=10, parameter_overrides=None, **kwargs)[source]

Subclass of ipyleaflet.TileLayer for displaying a Workflows Image or ImageCollection.

imagery

Read-only: the Image or ImageCollection to use. Change it with set_imagery.

Type

Image or ImageCollection

value

Read-only: a parametrized version of imagery, with all the values of parameters embedded in it.

Type

Image or ImageCollection

image_value

Read-only: a parametrized version of imagery as an Image, with any reduction applied and all the values of parameters embedded in it

Type

Image

parameters

Parameters to use while computing; modify attributes under .parameters (like layer.parameters.foo = "bar") to cause the layer to recompute and update under those new parameters. This trait is read-only in that you can’t do layer.parameters = a_new_parameter_set, but you can change the attributes within layer.parameters.

Type

ParameterSet

clear_on_update

Whether to clear all tiles from the map as soon as the layer changes, or leave out-of-date tiles visible until new ones have loaded. True (default) makes it easier to tell whether the layer is done loading and up-to-date or not. False prevents fast-loading layers from appearing to “flicker” as you interact with them.

Type

bool, default True

xyz_obj

Read-only: The XYZ object this layer is displaying.

Type

XYZ

session_id

Read-only: Unique ID that logs will be stored under, generated automatically.

Type

str

checkerboard

Whether to display a checkerboarded background for missing or masked data.

Type

bool, default True

colormap

Name of the colormap to use. If set, imagery must have 1 band.

Type

str, optional, default None

reduction

If displaying an ImageCollection, this method is used to reduce it into an Image. Reduction is performed before applying a colormap or scaling.

Type

{“min”, “max”, “mean”, “median”, “mosaic”, “sum”, “std”, “count”}

r_min

Min value for scaling the red band. Along with r_max, controls scaling when a colormap is enabled.

Type

float, optional, default None

r_max

Max value for scaling the red band. Along with r_min, controls scaling when a colormap is enabled.

Type

float, optional, default None

g_min

Min value for scaling the green band.

Type

float, optional, default None

g_max

Max value for scaling the green band.

Type

float, optional, default None

b_min

Min value for scaling the blue band.

Type

float, optional, default None

b_max

Max value for scaling the blue band.

Type

float, optional, default None

log_output

If set, write unique log records from tiles computation to this output area from a background thread. Setting to None stops the listener thread.

Type

ipywidgets.Output, optional, default None

log_level

Only listen for log records at or above this log level during tile computation. See https://docs.python.org/3/library/logging.html#logging-levels for valid log levels.

Type

int, default logging.DEBUG

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> # ^ display interactive map
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1").pick_bands("red")
>>> masked_img = img.mask(img > wf.parameter("threshold", wf.Float))
>>> layer = masked_img.visualize("sample", colormap="viridis", threshold=0.07) 
>>> layer.colormap = "plasma" 
>>> # ^ change colormap (this will update the layer on the map)
>>> layer.parameters.threshold = 0.13 
>>> # ^ adjust parameters (this also updates the layer)
>>> layer.set_scales((0.01, 0.3)) 
>>> # ^ adjust scaling (this also updates the layer)

Public constructor

Attributes:

attribution

A trait for unicode strings.

autoscale_progress

A trait whose value must be an instance of a specified class.

b_max

Casting Float traitlet that also considers the empty string as None

b_min

Casting Float traitlet that also considers the empty string as None

checkerboard

A boolean (True, False) trait.

clear_on_update

A boolean (True, False) trait.

colormap

A trait for unicode strings.

g_max

Casting Float traitlet that also considers the empty string as None

g_min

Casting Float traitlet that also considers the empty string as None

image_value

A trait whose value must be an instance of a specified class.

imagery

A trait type representing a Union type.

log_level

An int trait.

log_output

A trait whose value must be an instance of a specified class.

min_zoom

An int trait.

parameters

A trait whose value must be an instance of a specified class.

r_max

Casting Float traitlet that also considers the empty string as None

r_min

Casting Float traitlet that also considers the empty string as None

reduction

A trait for unicode strings.

session_id

A trait for unicode strings.

url

A trait for unicode strings.

value

A trait type representing a Union type.

xyz_obj

A trait whose value must be an instance of a specified class.

Methods:

clear_logs()

Clear any logs currently displayed for this layer

forget_logs()

Clear the set of known log records, so they are re-displayed if they occur again

get_scales()

Get scales for a layer.

hold_url_updates()

Context manager to prevent the layer URL from being updated multiple times.

make_url()

Generate the URL for this layer.

set_imagery(imagery, **parameter_overrides)

Set a new Image or ImageCollection object for this layer to use.

set_scales(scales[, new_colormap])

Update the scales for this layer by giving a list of scales

trait_has_value(name)

Returns True if the specified trait has a value.

clear_logs()[source]

Clear any logs currently displayed for this layer

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> layer = img.visualize("sample visualization") 
>>> # ^ will show an error for attempting to visualize more than 3 bands
>>> layer.clear_logs() 
>>> # ^ the errors will disappear
>>> wf.map.zoom = 10 
>>> # ^ attempting to load more tiles from img will cause the same error to appear
forget_logs()[source]

Clear the set of known log records, so they are re-displayed if they occur again

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> layer = img.visualize("sample visualization") 
>>> # ^ will show an error for attempting to visualize more than 3 bands
>>> layer.forget_logs() 
>>> wf.map.zoom = 10 
>>> # ^ attempting to load more tiles from img will cause the same error to appear
get_scales()[source]

Get scales for a layer.

Returns

scales – A list containing a list of scales for each band in the layer or None if the layer has no scales set.

Return type

List[List[int]] or None

Example

>>> import descarteslabs.workflows as wf
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1")
>>> img = img.pick_bands("red") 
>>> layer = img.visualize("sample visualization") 
>>> layer.set_scales((0.08, 0.3), 'viridis') 
>>> layer.get_scales() 
[[0.08, 0.3]]
hold_url_updates()[source]

Context manager to prevent the layer URL from being updated multiple times.

When leaving the context manager, the URL is always updated exactly once.

Also applies hold_trait_notifications.

Example

>>> import descarteslabs.workflows as wf
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img = img.pick_bands("red") 
>>> layer = img.visualize("sample visualization", colormap="viridis") 
>>> with layer.hold_url_updates(): 
...     layer.checkerboard = False 
...     layer.set_scales([0, 1], new_colormap="magma") 
...     layer.set_scales([0, 1], new_colormap="magma") 
>>> # ^ the layer will now update only once, instead of 3 times.
make_url()[source]

Generate the URL for this layer.

This is called automatically as the attributes (imagery, colormap, scales, etc.) are changed.

Example

>>> import descarteslabs.workflows as wf
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img = img.pick_bands("red blue green") 
>>> layer = img.visualize("sample") 
>>> layer.make_url() 
'https://workflows.descarteslabs.com/master/xyz/9ec70d0e99db7f50c856c774809ae454ffd8475816e05c5c/{z}/{x}/{y}.png?session_id=xxx&checkerboard=true'
set_imagery(imagery: Union[descarteslabs.workflows.types.geospatial.image.Image, descarteslabs.workflows.types.geospatial.imagecollection.ImageCollection], **parameter_overrides)[source]

Set a new Image or ImageCollection object for this layer to use. You can set/override the values of any parameters the imagery depends on by passing them as kwargs.

If the imagery depends on parameters that don’t have default values (created with wf.parameter("name", wf.Int) for example, versus wf.widget.input("name", default=1)), then you must pass values for those parameters.

Parameters

**parameter_overrides (JSON-serializable value, Proxytype, or ipywidgets.Widget) – Paramter names to values. Values can be Python types, Proxytype instances, or ipywidgets.Widget instances. Names must correspond to parameters that imagery depends on.

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> red = img.pick_bands("red") 
>>> blue = img.pick_bands("blue") 
>>> layer = red.visualize(name="sample visualization") 
>>> layer.set_imagery(blue) 
set_scales(scales, new_colormap=False)[source]

Update the scales for this layer by giving a list of scales

Parameters
  • scales (list of lists, default None) –

    The scaling to apply to each band in the Image or ImageCollection. If displaying an ImageCollection, it is reduced into an Image before applying scaling.

    If Image or ImageCollection contains 3 bands, scales must be a list like [(0, 1), (0, 1), (-1, 1)].

    If Image or ImageCollection contains 1 band, scales must be a list like [(0, 1)], or just (0, 1) for convenience

    If None, each 256x256 tile will be scaled independently based on the min and max values of its data.

  • new_colormap (str, None, or False, optional, default False) – A new colormap to set at the same time, or False to use the current colormap.

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img = img.pick_bands("red") 
>>> layer = img.visualize("sample visualization", colormap="viridis") 
>>> layer.set_scales((0.08, 0.3), new_colormap="plasma") 
>>> # ^ optionally set new colormap
trait_has_value(name)[source]

Returns True if the specified trait has a value.

This will return false even if getattr would return a dynamically generated default value. These default values will be recognized as existing only after they have been generated.

Example

class MyClass(HasTraits):
    i = Int()

mc = MyClass()
assert not mc.trait_has_value("i")
mc.i # generates a default value
assert mc.trait_has_value("i")
attribution

A trait for unicode strings.

autoscale_progress

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

b_max

Casting Float traitlet that also considers the empty string as None

b_min

Casting Float traitlet that also considers the empty string as None

checkerboard

A boolean (True, False) trait.

clear_on_update

A boolean (True, False) trait.

colormap

A trait for unicode strings.

g_max

Casting Float traitlet that also considers the empty string as None

g_min

Casting Float traitlet that also considers the empty string as None

image_value

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

imagery

A trait type representing a Union type.

log_level

An int trait.

log_output

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

min_zoom

An int trait.

parameters

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

r_max

Casting Float traitlet that also considers the empty string as None

r_min

Casting Float traitlet that also considers the empty string as None

reduction

A trait for unicode strings.

session_id

A trait for unicode strings.

url

A trait for unicode strings.

value

A trait type representing a Union type.

xyz_obj

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

class LayerController(map, **kwargs)[source]

An ipyleaflet.WidgetControl for managing WorkflowsLayer.

Unlike other ipyleaflet controls, a Map must be passed in on instantiation. Creating a LayerController automatically adds it to the given Map.

controller_list

The LayerControllerList widget displayed.

Type

LayerControllerList

Example

>>> import descarteslabs.workflows as wf
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1").pick_bands("red green blue")
>>> my_map = wf.Map()  
>>> layer = wf.WorkflowsLayer(img)  
>>> my_map.add_layer(layer)  
>>> ctl = wf.LayerController(my_map)  
>>> my_map  

Create the LayerController.

Parameters

map (Map) – The Map to which to add this control.

class LayerControllerList(map, control_tile_layers=True, control_other_layers=False)[source]

Widget displaying a list of LayerControllerRow widgets for a Map.

Example

>>> import descarteslabs.workflows as wf
>>> my_map = wf.Map() 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1").pick_bands("red") 
>>> img.visualize("sample visualization", map=my_map) 
>>> my_map 
>>> # ^ shows map with no layer controls
>>> layer_controller = wf.interactive.LayerControllerList(my_map) 
>>> layer_controller 
>>> # ^ shows layer controls as a separate widget
>>> layer_controller.children 
>>> # ^ list of individual widgets controlling each layer

Public constructor

Attributes:

control_other_layers

A boolean (True, False) trait.

control_tile_layers

A boolean (True, False) trait.

map

A trait whose value must be an instance of a specified class.

control_other_layers

A boolean (True, False) trait.

control_tile_layers

A boolean (True, False) trait.

map

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

class ImagePickerWidget(map=None, default_layer: Optional[descarteslabs.workflows.interactive.layer.WorkflowsLayer] = None, hide_deps_of: Optional[descarteslabs.workflows.types.core.core.Proxytype] = None, **kwargs)[source]

Widget to pick a layer from the map, as an Image.

If selecting an ImageCollection layer, this gives it with its reduction applied.

Note you cannot change the selected layer programmatically, only by using the widget.

Construct a LayerPicker widget for a map.

Parameters
  • map (ipyleaflet.Map) – The map instance to pick from. Defaults to wf.map.

  • default_layer (WorkflowsLayer) – The layer instance to have selected by default

  • hide_deps_of (Proxytype) – Hide any layers from the dropdown that have this object in their .params. Mainly used by the Picker parameter widget to hide its own layer from the dropdown, avoiding graft cycles.

Attributes:

value

A trait whose value must be an instance of a specified class.

value

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

class ImageCollectionPickerWidget(map=None, default_layer: Optional[descarteslabs.workflows.interactive.layer.WorkflowsLayer] = None, hide_deps_of: Optional[descarteslabs.workflows.types.core.core.Proxytype] = None, **kwargs)[source]

Widget to pick a layer from the map, as an ImageCollection.

Only layers showing ImageCollections (not Images) will be shown.

Note you cannot change the selected layer programmatically, only by using the widget.

Construct a LayerPicker widget for a map.

Parameters
  • map (ipyleaflet.Map) – The map instance to pick from. Defaults to wf.map.

  • default_layer (WorkflowsLayer) – The layer instance to have selected by default

  • hide_deps_of (Proxytype) – Hide any layers from the dropdown that have this object in their .params. Mainly used by the Picker parameter widget to hide its own layer from the dropdown, avoiding graft cycles.

class Map(**kwargs)[source]

Subclass of ipyleaflet.Map with Workflows defaults and extra helper methods.

output_log

Widget where functions doing operations on this map (especially compute operations, like autoscaling or timeseries) can log their output.

Type

ipywidgets.Output

Example

>>> import descarteslabs.workflows as wf
>>> from ipywidgets import HBox 
>>> map1 = wf.Map() 
>>> map2 = wf.Map() 
>>> HBox([map1, map2]) 
>>> # ^ view multiple maps in a custom layout

Public constructor

Attributes:

autoscale_outputs

A trait whose value must be an instance of a specified class.

center

An instance of a Python list.

inspecting_pixels

A boolean (True, False) trait.

logs

A trait whose value must be an instance of a specified class.

min_zoom

An int trait.

output_log

A trait whose value must be an instance of a specified class.

scroll_wheel_zoom

A boolean (True, False) trait.

zoom_start

An int trait.

Methods:

clear_layers()

Remove all layers from the map (besides the base layer)

geocontext([resolution, shape, crs])

A Scenes AOI representing the current view area and resolution of the map.

map_dimensions()

Width, height of this Map, in pixels.

move_layer(layer, new_index)

Move a layer to a new index.

move_layer_down(layer)

Move a layer down one, if not already at the bottom.

move_layer_up(layer)

Move a layer up one, if not already at the top.

remove_layer(layer_name)

Remove a named layer or layer instance from the map

clear_layers()[source]

Remove all layers from the map (besides the base layer)

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1")
>>> red = img.pick_bands("red").visualize("red layer") 
>>> wf.map.clear_layers() 
geocontext(resolution=None, shape=None, crs='EPSG:3857')[source]

A Scenes AOI representing the current view area and resolution of the map. The bounds of the of the returned geocontext are the current bounds of the map viewport.

Parameters
  • crs (str, default "EPSG:3857") – Coordinate reference system into which data will be projected, expressed as an EPSG code (like EPSG:4326), PROJ.4 definition, or "utm". If crs is "utm", the zone is calculated automatically from lat, lng of map center. Defaults to the Web Mercator projection (EPSG:3857).

  • resolution (float, default: None) – Distance, in units of the crs, that the edge of each pixel represents on the ground. Only one of resolution or shape can be given. If neither shape nor resolution is given, shape defaults to the current dimensions of the map viewport.

  • shape (tuple, default: None) – The dimensions (rows, columns), in pixels, to fit the output array within. Only one of resolution or shape can be given. If neither shape nor resolution is given, shape defaults to the current dimensions of the map viewport.

Example

>>> import descarteslabs.workflows as wf
>>> wf.map.geocontext() 
AOI(geometry=None,
    resolution=None,
    crs='EPSG:3857',
    align_pixels=False,
    bounds=(-106.14303588867188, 35.631349127185125, -105.73276519775392, 35.7428898051826),
    bounds_crs='EPSG:4326',
    shape=(1195, 398))
>>> wf.map.geocontext(crs="utm") 
AOI(geometry=None,
    resolution=None,
    crs='+proj=utm +zone=13 +datum=WGS84 +units=m +no_defs ',
    align_pixels=False,
    bounds=(-106.14303588867188, 35.631349127185125, -105.73276519775392, 35.7428898051826),
    bounds_crs='EPSG:4326',
    shape=(1195, 398))
>>> wf.map 
Returns

geoctx

Return type

descarteslabs.scenes.AOI

map_dimensions()[source]

Width, height of this Map, in pixels.

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> wf.map.map_dimensions() 
(1182, 398)
move_layer(layer, new_index)[source]

Move a layer to a new index. Indices are one-indexed.

Parameters
  • layer (ipyleaflet.Layer) – Leaflet layer object to move

  • new_index (Int) – Index to move layer to. Indices are one-indexed.

Raises

ValueError – If layer is a base layer, or does not already exist on the map.

Example

>>> import descarteslabs.workflows as wf
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1")
>>> red_layer = img.pick_bands("red").visualize("red layer") 
>>> blue = img.pick_bands("blue").visualize("blue layer") 
>>> wf.map.move_layer(red_layer, 2) 
>>> # "red layer" will now be displayed on top of "blue layer"
>>> wf.map 
move_layer_down(layer)[source]

Move a layer down one, if not already at the bottom.

Parameters

layer (ipyleaflet.Layer) –

Raises

ValueError – If layer is a base layer, or does not already exist on the map.

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1")
>>> red = img.pick_bands("red").visualize("red layer") 
>>> blue_layer = img.pick_bands("blue").visualize("blue layer") 
>>> wf.map.move_layer_down(blue_layer) 
>>> # ^ display blue_layer below red_layer
move_layer_up(layer)[source]

Move a layer up one, if not already at the top.

Parameters

layer (ipyleaflet.Layer) –

Raises

ValueError – If layer is a base layer, or does not already exist on the map.

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1")
>>> red_layer = img.pick_bands("red").visualize("red layer") 
>>> blue = img.pick_bands("blue").visualize("blue layer") 
>>> wf.map.move_layer_up(red_layer) 
>>> # ^ display red_layer above blue_layer
remove_layer(layer_name)[source]

Remove a named layer or layer instance from the map

Parameters

layer_name (Str or ipyleaflet.Layer) – Name of the layer or Layer instance to remove

Example

>>> import descarteslabs.workflows as wf
>>> wf.map 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1")
>>> red = img.pick_bands("red").visualize("red layer") 
>>> blue = img.pick_bands("blue").visualize("blue layer") 
>>> wf.map.remove_layer("red layer") 
>>> # ^ remove "red layer" from the map (by name)
autoscale_outputs

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

center

An instance of a Python list.

inspecting_pixels

A boolean (True, False) trait.

logs

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

min_zoom

An int trait.

output_log

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

scroll_wheel_zoom

A boolean (True, False) trait.

zoom_start

An int trait.

class MapApp(map=None, layer_controller_list=None, map_controller=None)[source]

Widget displaying a map, layers, and output logs in a nicer layout.

Forwards attributes and methods to self.map.

Note: to change the size of the map when displayed inline in a notebook, set wf.map.map.layout.height = "1000px". (wf.map.map is the actual map widget, wf.map is the container with the layer controls, which will resize accordingly.) Setting the height on just wf.map will also work, but if you use an output view, then the map won’t resize itself to fit in within it.

Example

>>> import descarteslabs.workflows as wf
>>> from ipywidgets import HBox 
>>> map1 = wf.interactive.MapApp() 
>>> map2 = wf.interactive.MapApp() 
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img1 = img.pick_bands("red") 
>>> img2 = img.pick_bands("nir") 
>>> img1.visualize("red band", map=map1) 
>>> img2.visualize("nir band", map=map2) 
>>> # ^ view the red band on map1 and the nir band on map2
>>> HBox([map1, map2]) 
>>> # ^ view the two maps in a custom layout
>>> ctx = map1.geocontext() 
>>> # get the geocontext of the first map

Public constructor

Attributes:

control_other_layers

A boolean (True, False) trait.

control_tile_layers

A boolean (True, False) trait.

control_other_layers

A boolean (True, False) trait.

control_tile_layers

A boolean (True, False) trait.

class ParameterSet(notify_object, notify_name, **traits)[source]

Parameters for a WorkflowsLayer, which updates the layer when new values are assigned.

A ParameterSet is constructed automatically when calling Image.visualize and added to the WorkflowsLayer; you shouldn’t construct one manually.

You can access a widget for interactively controlling these parameters at widget.

widget

A widget showing a table of controls, linked to this ParameterSet. Updating the controls causes the map to update.

Type

ipywidgets.Widget

Example

>>> import descarteslabs.workflows as wf
>>> imgs = wf.ImageCollection.from_id(
...     "sentinel-1:GRD", start_datetime=wf.parameter("start", wf.Datetime)
... )
>>> filtered = imgs.filter(lambda img: img.properties['pass'] == wf.parameter("pass_dir", wf.Str))
>>> composite = imgs.mean(axis="images").pick_bands("vv")
>>> lyr = composite.visualize("vv mean", start=wf.Datetime(2018), pass_dir="ASCENDING")  
>>> params = lyr.parameters  
>>> # ^ get the ParameterSet for the layer
>>> params.pass_dir  
"ASCENDING"
>>> params.pass_dir = "DESCENDING"  
>>> # ^ this updates the layer on the map
>>> params.start = "2019-01-01"  
>>> # ^ as does this
>>> params.link("start", my_ipywidget)  
>>> # ^ this links the "start" parameter to an ipywidget's value

Notes

The names and types of fields on a ParameterSet are fixed, and can only be changed using update. This means that on a ParameterSet that only has the field x, which holds a float, params.x = "foo" will fail (wrong type), as will params.y = "bar" (y doesn’t exist).

When Image.visualize creates a ParameterSet for you, it adds fields for whichever parameter the imagery depends on. If img depends on wf.widgets.slider("slidey", 0, 1) and wf.parameter("td", wf.Timedelta) for example, then img.visualize("my layer", td=wf.Timedelta(days=2)) will create the fields slidey and td. More importantly, it infers the type of those fields from their parameter types, so slidey would only accept floats, and td would only accept Timedeltas.

Therefore, if you experience a TypeError assiging to a ParameterSet field, you may need to change types of the initial parameters img depends on.

You shouldn’t need to construct a ParameterSet manually, but here’s how you would:

Parameters
  • notify_object (traitlets.HasTraits instance) – The object to notify when any of the traits on this ParameterSet change

  • notify_name (str) – The name to use in the change notification sent to that object

  • **traits (traitlets.TraitType instances) – The traits to add to this ParameterSet

Methods:

add_traits(**traits)

Dynamically add trait attributes to the HasTraits instance.

link(name, target[, attr])

Link an attribute to an ipywidget (or other object).

make_widget([skip])

Make a widget for controlling these parameters.

remove_traits(*names)

Remove traits that were dynamically added to the HasTraits instance

to_dict()

Key-value pairs of the parameters, in order.

update(**new_values)

Update the ParameterSet with new values.

add_traits(**traits)[source]

Dynamically add trait attributes to the HasTraits instance.

If you are manipulating a ParameterSet generated from a layer, instead use update, which handles adding and removing traits in a more delclarative way.

Example

>>> import traitlets
>>> import descarteslabs.workflows as wf
>>> class Listener(traitlets.HasTraits):
...     @traitlets.observe("param")
...     def handler(self, change):
...         print(change['key'])
...         print(change)
>>> listener = Listener()
>>> ps = wf.interactive.ParameterSet(listener, "param", foo=traitlets.Float()) 
>>> ps.foo = 1.1 
foo
{'name': 'param',
 'old': 0.0,
 'new': 1.1,
 'owner': ParameterSet({'foo': 1.1}),
 'type': 'change',
 'key': 'foo'
 }
>>> ps.bar = "baz" 
>>> # ^ nothing is printed, `bar` is not a trait
>>> ps.add_traits(bar=traitlets.Unicode()) 
>>> ps.bar 
''
>>> ps.bar = "quix" 
bar
{'name': 'param',
 'old': '',
 'new': 'quix',
 'owner': ParameterSet({'bar': 'quix', 'foo': 1.1}),
 'type': 'change',
 'key': 'bar'
 }

Link an attribute to an ipywidget (or other object).

If a link to the attribute was previously created, it is unlinked.

Parameters
  • name (str) – The name of the parameter to link

  • target (ipywidgets.Widget, any traitlets.HasTraits instance, or None) – The object to link to. If None, any existing link to name is removed.

  • attr (str, default "value") – The name of the attribute on target to link to. Defaults to "value", since that works for most ipywidgets.

Example

>>> import descarteslabs.workflows as wf
>>> from ipywidgets import FloatSlider
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img = img.pick_bands("red") 
>>> masked_img = img.mask(img > wf.parameter("threshold", wf.Float)) 
>>> layer = masked_img.visualize("sample", colormap="plasma", threshold=0.07) 
>>> layer.parameters.link("threshold", my_ipywidget) 
>>> # ^ links the "threshold" parameter to an ipywidget's value
>>> layer2 = masked_img.visualize("sample", colormap="plasma", threshold=0.3) 
>>> layer2.parameters.link("threshold", layer.parameters, attr="threshold") 
>>> # ^ now the `threshold` parameter is linked between `layer` and `layer2`
>>> widget = FloatSlider(min=0, max=1) 
>>> layer2.parameters.link("threshold", widget) 
>>> # ^ now `threshold` is linked to the widget, and the link is broken to `layer`
make_widget(skip=None)[source]

Make a widget for controlling these parameters.

Widgets that were passed in or linked are displayed. For values that aren’t already linked to a widget, an appropriate widget type is chosen if possible.

Note that this widget can become out of date and unlinked once update is called; use the widget property for an always-up-to-date widget.

Parameters

skip (list[str]) – Sequence of parameter names to not include in the widget

Returns

widget – A widget showing a table of controls, linked to this ParameterSet. Updating the widgets causes the map to update. If there are no parameters to display, returns None.

Return type

ipywidgets.Widget or None

Example

>>> import traitlets
>>> import descarteslabs.workflows as wf
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img = img.pick_bands("red") 
>>> masked_img = img.mask(img > wf.parameter("threshold", wf.Float)) 
>>> layer = masked_img.visualize("sample", colormap="plasma", threshold=0.07, sample_param=0.0) 
>>> layer.parameters.make_widget(skip=["sample_param"]) 
>>> # ^ displays a widget for modifying a layer's parameters, optionally skipping params
remove_traits(*names)[source]

Remove traits that were dynamically added to the HasTraits instance

If you are manipulating a ParameterSet generated from a layer, instead use update, which handles adding and removing traits in a more delclarative way.

Example

>>> import traitlets
>>> import descarteslabs.workflows as wf
>>> class Listener(traitlets.HasTraits):
...     @traitlets.observe("param")
...     def handler(self, change):
...         print(change['key'])
...         print(change)
>>> listener = Listener()
>>> ps = wf.interactive.ParameterSet(listener, "param", foo=traitlets.Float()) 
>>> ps.foo = 1.1 
foo
{'name': 'param',
 'old': 0.0,
 'new': 1.1,
 'owner': ParameterSet({'foo': 1.1}),
 'type': 'change',
 'key': 'foo'
 }
>>> ps.add_traits(bar=traitlets.Unicode()) 
>>> ps.bar = 'quix' 
bar
{'name': 'param',
 'old': '',
 'new': 'quix',
 'owner': ParameterSet({'bar': 'quix', 'foo': 1.1}),
 'type': 'change',
 'key': 'bar'
 }
>>> ps.remove_traits("foo") 
>>> ps.foo = 2.2 
>>> # ^ nothing is printed, `foo` is no longer a trait
>>> ps.to_dict() 
{'bar': 'quix'}
to_dict()[source]

Key-value pairs of the parameters, in order.

Example

>>> import descarteslabs.workflows as wf
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img = img.pick_bands("red") 
>>> masked_img = img.mask(img > wf.parameter("threshold", wf.Float)) 
>>> layer = masked_img.visualize("sample", colormap="plasma", threshold=0.07) 
>>> layer.parameters.to_dict() 
{'threshold': 0.07}
update(**new_values)[source]

Update the ParameterSet with new values.

New parameters are added as fields on the ParameterSet, with their trait type inferred from the value.

Current parameters that are not present in new_values are removed from the ParameterSet.

Passing a value of a different type to a current parameter will change its trait type.

If a value is an ipywidgets Widget, it will be linked (via its "value" attribute) to that parameter. If a parameter was previously linked to a widget, and a different widget instance (or non-widget) is passed for its new value, the old widget is automatically unlinked. If the same widget instance is passed as is already linked, no change occurs.

The ParameterSet will be reordered to the order of these new values.

Parameters

**new_values (JSON-serializable value, Proxytype, or ipywidgets.Widget) – Parameter names to new values. Values can be Python types, Proxytype instances, or ipywidgets.Widget instances.

Example

>>> import descarteslabs.workflows as wf
>>> from ipywidgets import FloatSlider
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1") 
>>> img = img.pick_bands("red") 
>>> masked_img = img.mask(img > wf.parameter("threshold", wf.Float)) 
>>> layer = masked_img.visualize("sample", colormap="plasma", threshold=0.07) 
>>> scaled_img = img * wf.parameter("scale", wf.Float) + wf.parameter("offset", wf.Float) 
>>> with layer.hold_trait_notifications(): 
...     layer.imagery = scaled_img 
...     layer.parameters.update(scale=FloatSlider(min=0, max=10, value=2), offset=2.5) 
>>> # ^ re-use the same layer instance for a new Image with different parameters
class ProxytypeInstance(klass=None, args=None, kw=None, **kwargs)[source]

Trait type that tries to promote values to a given Proxytype

Example

>>> import traitlets
>>> import descarteslabs.workflows as wf
>>> from descarteslabs.workflows.interactive import ProxytypeInstance
>>> class ProxyTraits(traitlets.HasTraits): 
...     int_list = ProxytypeInstance(klass=wf.List[wf.Int]) 
...     @traitlets.observe('int_list') 
...     def int_list_changed(self, change): 
...         print(f"new int list: {change['new']}") 
>>> pt = ProxyTraits() 
>>> pt.int_list = [1, 2, 3] 
new int list: <descarteslabs.workflows.types.containers.list_.List[Int] object at 0x...>
>>> pt.int_list = [1, 2, "not an int"] 
TraitError: For parameter 'int_list', could not promote [1, 2, 'not an int']
to <class 'descarteslabs.workflows.types.containers.list_.List[Int]'>: List[Int]:
Expected iterable values of type <class 'descarteslabs.workflows.types.primitives.number.Int'>,
but for item 2, got 'not an int'

Construct an Instance trait.

This trait allows values that are instances of a particular class or its subclasses. Our implementation is quite different from that of enthough.traits as we don’t allow instances to be used for klass and we handle the args and kw arguments differently.

Parameters
  • klass (class, str) – The class that forms the basis for the trait. Class names can also be specified as strings, like ‘foo.bar.Bar’.

  • args (tuple) – Positional arguments for generating the default value.

  • kw (dict) – Keyword arguments for generating the default value.

  • allow_none (bool [ default False ]) – Indicates whether None is allowed as a value.

  • **kwargs – Extra kwargs passed to ClassBasedTraitType

Notes

If both args and kw are None, then the default value is None. If args is a tuple and kw is a dict, then the default is created as klass(*args, **kw). If exactly one of args or kw is None, the None is replaced by () or {}, respectively.

Methods:

validate(obj, value)

validate(obj, value)[source]
class PixelInspector(map, position='topright', layout=None)[source]

Display pixel values when clicking on the map.

Whenever you click on the map, it fetches the pixel values at that location for all active Workflows layers and displays them in a table overlaid on the map. It also shows a marker on the map indicating the last position clicked. As layers change, or are added or removed, the table keeps fetching pixel values for the new layers at the last-clicked point (the marker’s current position).

For performance, the inspector does not use full-resolution data, but rather whatever resolution (zoom level) the map is currently displaying. Therefore, it’s possible that values for the same point would come back slightly different at different zoom levels. (Note that the resampling method used is whatever the input Image or ImageCollection was constructed with.)

To unlink from the map, call unlink.

Example

>>> import descarteslabs.workflows as wf
>>> my_map = wf.interactive.Map()
>>> img = wf.Image.from_id("landsat:LC08:PRE:TOAR:meta_LC80330352016022_v1").pick_bands("red")
>>> img.pick_bands("red").visualize("Red", colormap="Reds", map=my_map)  
>>> img.pick_bands("green").visualize("Green", colormap="Greens", map=my_map)  
>>> inspector = wf.interactive.PixelInspector(my_map)
>>> my_map  
>>> # ^ display the map
>>> # click on the map; a table will pop up showing pixel values for the Red and Green layers
>>> inspector.unlink()
>>> # table and marker disappear; click again and nothing happens

Construct a PixelInspector and attach it to a map.

Parameters
  • map (ipyleaflet.Map, workflows.interactive.MapApp) – The map to attach to

  • position (str, optional, default "topright") – Where on the map to display the values table

  • layout (ipywidgets.Layout, optional) – Layout for the values table. Defaults to Layout(max_height="350px", overflow="scroll", padding="4px")

Attributes:

marker

A trait whose value must be an instance of a specified class.

n_bands

An int trait.

Methods:

unlink()

Stop listening for click events or layer updates and remove the table from the map

Stop listening for click events or layer updates and remove the table from the map

marker

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

n_bands

An int trait.

class WorkflowsBrowser(map=None, **kwargs)[source]

Widget displaying a UI for browsing and searching Workflow objects, and displaying them on the map.

name

The name prefix used in the search

Type

str

mine

Whether to seach for only the current user’s Workflows. If True, email is ignored.

Type

bool

email

The email used in the search

Type

str

selected_id

The currently-selected Workflow ID (like you@example.com:workflow_name).

Type

str

selected_version

The currently-selected version name (like 1.2.0).

Type

str

map

Map instance used by the “Add to map” button and add_current_to_map. Defaults to wf.map.

Type

ipyleaflet.Map, MapApp

flows

List of Workflow objects currently being displayed that matched the search. Read-only.

Type

List[Workflow]

current_flow

The currently-selected Workflow object, or None.

Type

Optional[Workflow]

current_vg

The currently-selected VersionedGraft object, or None.

Type

Optional[VersionedGraft]

Example

>>> import descarteslabs.workflows as wf
>>> wf.flows  
>>> # displays the Workflow browser widget

Public constructor

Methods:

add_current_to_map()

Add the currently-selected Workflow to wf.map or self.map, if possible.

Attributes:

current_flow

A trait whose value must be an instance of a specified class.

current_vg

A trait whose value must be an instance of a specified class.

email

A trait for unicode strings.

flows

An instance of a Python list.

mine

A boolean (True, False) trait.

name

A trait for unicode strings.

selected_id

A trait for unicode strings.

selected_version

A trait for unicode strings.

add_current_to_map()[source]

Add the currently-selected Workflow to wf.map or self.map, if possible.

The Workflow must be one of these types:

If the version has viz_options, the first VizOption will be used to style the layer on the map.

If self.map is None, the layer will be added to wf.map, otherwise to self.map.

Returns

lyr – The layer added to the map

Return type

WorkflowsLayer

Raises
  • ValueError – If a Workflow and version are not currently selected. If the currently-selected Workflow and version is incompatible with this client version.

  • TypeError – If the selected version is not one of the supported types.

current_flow

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

current_vg

A trait whose value must be an instance of a specified class.

The value can also be an instance of a subclass of the specified class.

Subclasses can declare default classes by overriding the klass attribute

email

A trait for unicode strings.

flows

An instance of a Python list.

mine

A boolean (True, False) trait.

name

A trait for unicode strings.

selected_id

A trait for unicode strings.

selected_version

A trait for unicode strings.

map = `ipyleaflet` and/or `ipywidgets` Jupyter extensions are not installed! (or you're not in a Jupyter notebook.) To install for JupyterLab, run this in a cell: !jupyter labextension install jupyter-leaflet @jupyter-widgets/jupyterlab-manager To install for plain Jupyter Notebook, run this in a cell: !jupyter nbextension enable --py --sys-prefix ipyleaflet Then, restart the kernel and refresh the webpage.

A single MapApp instance that all visualize calls are automatically added to. This is the best starting point for using Workflows interactive maps.

Run:

wf.map

in a JupyterLab cell to display the map the first time, then right-click and select “New View for Output”. You can then position and rearrange the map as a tab however you like.

Calling Image.visualize will by default add new layers to this map.

flows = WorkflowsBrowser(children=(HBox(children=(Button(icon='repeat', layout=Layout(overflow='visible', width='initial'), style=ButtonStyle(), tooltip='Reload'), Text(value='', description='Name prefix:'), Checkbox(value=False, description='Only mine'), Text(value='', description='Email:'), HTML(value=''))), HTML(value='<hr>'), WorkflowsListerWidget(children=(VBox(children=(HTML(value='<h2>Workflows</h2>'), Select(layout=Layout(height='100%', width='initial'), options=(), value=None)), layout=Layout(flex='1 0 auto', grid_area='widget001')), WorkflowWidget(layout=Layout(flex='1 0 auto', grid_area='widget002')), VersionGraftWidget(value='', layout=Layout(flex='1 0 auto', grid_area='widget003'))), layout=Layout(grid_gap='10px', grid_template_areas='"widget001 widget002 widget003"', grid_template_columns='repeat(3, 1fr)', grid_template_rows='repeat(1, 1fr)')), HTML(value='<hr>'), HBox(children=(HTML(value=''), Button(button_style='info', description='Add to map', style=ButtonStyle())), layout=Layout(justify_content='space-between'))))

Browse shared Workflow objects (and add them to the map) with a predefined WorkflowsBrowser instance.