Links
📊

Working with chart data

This is still an experimental feature and is currently only possible in code blocks added to the workflow. The definition of ChartData object can change before the feature becomes available throughout the whole platform
By using one of the code blocks, you can return a new type of object in the entrypoint function - ChartData . Objects of these type allow us to automatically generate the data in tabular format and prepare it to be displayed in the workflow preview section (for you to tweak them) as well as in the end user view of your application.
As with all the other products of executing the workflow, chart data is persisted after generation for a quick and seamless access.
Charts produced by the application's workflow displayed in the application

Chart data object

Property
Type
Description
title
str (required)
Defines chart's title
data
ee.FeatureCollection (required)
Data to be plotted in the chart
options
dict[str]
Options to be passed when generating the chart

Available options

  • chart_type - can be one of line, bar
  • unit_name - optional string describing the unit - will be shown as a label on the y-axis

Sample code (OrbEE)

When using our OrbEE library, generating charts is simplified through the usage of generic calculate_average_index function or more specialised s2_vegetation_indices.
Both functions produce map, chart and computed_variables outputs.
(...)
​
def entrypoint(dates: list[date], region: ee.Geometry) -> ReturnType:
# Calculate average index of SO2 concentration
so2 = oe.calculate_average_index(
dates,
region,
"COPERNICUS/S5P/NRTI/L3_SO2",
"SO2_column_number_density",
"SO2",
"bar",
)
# Calculate vegetation indices (NDVI, NDMI are default)
vegetation_indices = oe.s2_vegetation_indices(dates, region)
​
return [
so2["chart"],
vegetation_indices["chart"]
]

Sample code (advanced)

from datetime import date
from typing import Any, List, Union
​
import ee
​
from output import ChartData, NamedLayer
​
ComputedVariables = dict[str, Any]
​
# entrypoint function's return type allows to return `ChartData` objects
ReturnType = List[
Union[
ee.Image,
ee.Geometry,
ee.FeatureCollection,
ee.Feature,
ComputedVariables,
ChartData,
NamedLayer,
]
]
​
​
def entrypoint(dates: list[date], region: ee.Geometry) -> ReturnType:
def calculate_mean(image: ee.Image) -> ee.FeatureCollection:
"""
Use `reduceRegions` on every image in the collection to build
a collection of features with calculated `mean` property
(result of executing `ee.Reducer.mean`)
In order to properly index the chart data - by image's acquisition
timestamp, "system:time_start" property needs to be copied from
the input image into the collection of features built by reducer.
"""
return image.reduceRegions(
collection=ee.FeatureCollection(region),
reducer=ee.Reducer.mean(),
scale=1000
).map(
lambda feature: feature.copyProperties(image, ["system:time_start"]
)
)
# Fetch `absorbing_aerosol_index` from L3_AER_AI collection filtered by dates
absorbing_aerosol_index = (
ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_AER_AI")
.filter(ee.Filter.date("2020-01-01", "2021-01-01"))
.select("absorbing_aerosol_index")
)
# Build chart data for provided region. `reduceRegions` produces collection
# of collections, which means `flatten()` needs to be used on the result
# to generate a flat FeatureCollection object
aerosol_index_chart_data = (
absorbing_aerosol_index
.filterBounds(region)
.map(calculate_mean)
.flatten()
)
​
aerosol_index_chart = ChartData(
name="Absorbing aerosol (mean)",
data=aerosol_index_chart_data,
options={
"chart_type": "line"
}
)
​
return [aerosol_index_chart]