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 WorkflowsImage
orImageCollection
.-
imagery
¶ Read-only: the
Image
orImageCollection
to use. Change it withset_imagery
.Type: Image or ImageCollection
-
value
¶ Read-only: a parametrized version of
imagery
, with all the values ofparameters
embedded in it.Type: Image or ImageCollection
-
image_value
¶ Read-only: a parametrized version of
imagery
as anImage
, with anyreduction
applied and all the values ofparameters
embedded in itType: Image
-
parameters
¶ Parameters to use while computing; modify attributes under
.parameters
(likelayer.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 dolayer.parameters = a_new_parameter_set
, but you can change the attributes withinlayer.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 anImage
. 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
orImageCollection
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
orImageCollection
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, versuswf.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, oripywidgets.Widget
instances. Names must correspond to parameters thatimagery
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
orImageCollection
. If displaying anImageCollection
, it is reduced into anImage
before applying scaling.If
Image
orImageCollection
contains 3 bands,scales
must be a list like[(0, 1), (0, 1), (-1, 1)]
.If
Image
orImageCollection
contains 1 band,scales
must be a list like[(0, 1)]
, or just(0, 1)
for convenienceIf 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
- scales (list of lists, default None) –
-
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 managingWorkflowsLayer
.Unlike other ipyleaflet controls, a
Map
must be passed in on instantiation. Creating aLayerController
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 aMap
.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
Show generic controls for other ipyleaflet layer types control_tile_layers
Show controls for `ipyleaflet.TileLayer`s map
The map being controlled -
control_other_layers
¶ Show generic controls for other ipyleaflet layer types
-
map
¶ The map being controlled
-
-
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
- map (ipyleaflet.Map) – The map instance to pick from. Defaults to
-
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.
- map (ipyleaflet.Map) – The map instance to pick from. Defaults to
-
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
Widget containing all layers’ autoscale output widgets center
Initial geographic center of the map inspecting_pixels
Whether the pixel inspector is active, and clicking on the map displays pixel values logs
Widget where tiles layers can write their log messages. min_zoom
Minimum allowable zoom level of the map output_log
Widget where functions doing operations on this map (especially compute operations) can log their output. scroll_wheel_zoom
Whether the map can be zoomed by using the mouse wheel zoom_start
Initial map zoom level Methods:
clear_layers
()Remove all layers from the map (besides the base layer) geocontext
([resolution, shape, crs])A 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
AOI
representing the current view area and resolution of the map. Thebounds
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 ofresolution
orshape
can be given. If neithershape
norresolution
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
orshape
can be given. If neithershape
norresolution
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.geo.AOI - crs (str, default "EPSG:3857") – Coordinate reference system into which data will be projected,
expressed as an EPSG code (like
-
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
¶ Widget containing all layers’ autoscale output widgets
-
center
¶ Initial geographic center of the map
-
inspecting_pixels
¶ Whether the pixel inspector is active, and clicking on the map displays pixel values
-
logs
¶ Widget where tiles layers can write their log messages.
-
min_zoom
¶ Minimum allowable zoom level of the map
-
output_log
Widget where functions doing operations on this map (especially compute operations) can log their output.
-
scroll_wheel_zoom
¶ Whether the map can be zoomed by using the mouse wheel
-
zoom_start
¶ Initial map zoom level
-
-
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 justwf.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
Show generic controls for other ipyleaflet layer types control_tile_layers
Show controls for `ipyleaflet.TileLayer`s -
control_other_layers
¶ Show generic controls for other ipyleaflet layer types
-
-
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 callingImage.visualize
and added to theWorkflowsLayer
; 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 usingupdate
. This means that on aParameterSet
that only has the fieldx
, which holds a float,params.x = "foo"
will fail (wrong type), as willparams.y = "bar"
(y
doesn’t exist).When
Image.visualize
creates aParameterSet
for you, it adds fields for whichever parameter the imagery depends on. Ifimg
depends onwf.widgets.slider("slidey", 0, 1)
andwf.parameter("td", wf.Timedelta)
for example, thenimg.visualize("my layer", td=wf.Timedelta(days=2))
will create the fieldsslidey
andtd
. More importantly, it infers the type of those fields from their parameter types, soslidey
would only accept floats, andtd
would only accept Timedeltas.Therefore, if you experience a
TypeError
assiging to aParameterSet
field, you may need to change types of the initial parametersimg
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
(name, target, attr='value')[source]¶ 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 thewidget
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 theParameterSet
.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, oripywidgets.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
andkw
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
andkw
are None, then the default value is None. Ifargs
is a tuple andkw
is a dict, then the default is created asklass(*args, **kw)
. If exactly one ofargs
orkw
is None, the None is replaced by()
or{}
, respectively.Methods:
validate
(obj, value)
-
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
orImageCollection
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 -
unlink
()[source]¶ 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
-
email
¶ The email used in the search
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 towf.map
.Type: ipyleaflet.Map, MapApp
-
flows
¶ List of
Workflow
objects currently being displayed that matched the search. Read-only.Type: List[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
towf.map
orself.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
towf.map
orself.map
, if possible.The
Workflow
must be one of these types:Image
ImageCollection
Function
, in which case it must return anImage
orImageCollection
, and only takeInt
,Float
,Str
,Bool
, orDatetime
as parameters. A widget will be added to the map to control the function arguments interactively.
If the version has
viz_options
, the firstVizOption
will be used to style the layer on the map.If
self.map
is None, the layer will be added towf.map
, otherwise toself.map
.Returns: lyr – The layer added to the map
Return type: 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 allvisualize
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 predefinedWorkflowsBrowser
instance.