Visualise data with xcube viewer
How to visualise data with xcube viewer in your workspace¶
A DeepESDL example notebook¶
This notebook demonstrates how to use the features of the xcube JupyterLab integration.
The notebook demonstrates three scenarios how xcube Viewer is utilized in JupyterLab.
In particular, we open xcube Viewer for any xarray.Dataset
instances
- persisted in team s3 storage (saved datasets)
- opened or otherwise created in this Notebook (in-memory datasets)
- using a configuration file for customising stlyes.
To explore the xcube viewer functionalities, please checkout the documentation: https://xcube.readthedocs.io/en/latest/viewer.html#functionality
Please, also refer to the DeepESDL documentation and visit the platform's website for further information!
Brockmann Consult, 2024
This notebook runs with the python environment deepesdl-xcube-1.7.0
, please checkout the documentation for help on changing the environment.
First, lets create a small cube, which we can visualise with xcube viewer. We will use ESA CCI data for this. Please head over to example notebook in xcube-datastores: Generate CCI data cubes to get more details about the xcube-cci data store :)
from xcube.core.store import new_data_store
import os
store = new_data_store('cciodp')
store
<xcube_cci.dataaccess.CciOdpDataStore at 0x7f9af651fa90>
We request a dataset from the datasore:
dataset = store.open_data('esacci.SST.day.L4.SSTdepth.multi-sensor.multi-platform.OSTIA.2-1.sst',
variable_names=['analysed_sst'],
time_range=['1981-09-01','1981-09-07'])
dataset
<xarray.Dataset> Size: 1GB Dimensions: (time: 7, lat: 3600, lon: 7200, bnds: 2) Coordinates: * lat (lat) float32 14kB -89.97 -89.93 -89.88 ... 89.88 89.93 89.97 lat_bnds (lat, bnds) float32 29kB dask.array<chunksize=(3600, 2), meta=np.ndarray> * lon (lon) float32 29kB -180.0 -179.9 -179.9 ... 179.9 179.9 180.0 lon_bnds (lon, bnds) float32 58kB dask.array<chunksize=(7200, 2), meta=np.ndarray> * time (time) datetime64[ns] 56B 1981-09-01T12:00:00 ... 1981-09-0... time_bnds (time, bnds) datetime64[ns] 112B dask.array<chunksize=(7, 2), meta=np.ndarray> Dimensions without coordinates: bnds Data variables: analysed_sst (time, lat, lon) float64 1GB dask.array<chunksize=(1, 1200, 2400), meta=np.ndarray> Attributes: Conventions: CF-1.7 title: esacci.SST.day.L4.SSTdepth.multi-sensor.multi-pl... date_created: 2024-09-18T08:07:18.447033 processing_level: L4 time_coverage_start: 1981-09-01T00:00:00 time_coverage_end: 1981-09-08T00:00:00 time_coverage_duration: P7DT0H0M0S history: [{'program': 'xcube_cci.chunkstore.CciChunkStore...
Next, save it to the team s3 storage:
To store the cube in your teams user space, please first retrieve the details from your environment variables as the following:
S3_USER_STORAGE_KEY = os.environ["S3_USER_STORAGE_KEY"]
S3_USER_STORAGE_SECRET = os.environ["S3_USER_STORAGE_SECRET"]
S3_USER_STORAGE_BUCKET = os.environ["S3_USER_STORAGE_BUCKET"]
You need to instantiate a s3 datastore pointing to the team bucket:
team_store = new_data_store("s3",
root=S3_USER_STORAGE_BUCKET,
storage_options=dict(anon=False,
key=S3_USER_STORAGE_KEY,
secret=S3_USER_STORAGE_SECRET))
If you have stored no data to your user space, the returned list will be empty:
list(team_store.get_data_ids())
['SST.levels', 'amazonas_v8.zarr', 'amazonas_v9.zarr', 'analysed_sst.zarr', 'noise_trajectory.zarr']
The writing will take a few moments, as the data is global and will be persisted into the team s3 storage.
output_id = 'analysed_sst.zarr'
team_store.write_data(dataset, output_id)
'analysed_sst.zarr'
If you list the content of you datastore again, you will now see the newly written dataset in the list:
list(team_store.get_data_ids())
['SST.levels', 'amazonas_v8.zarr', 'amazonas_v9.zarr', 'analysed_sst.zarr', 'noise_trajectory.zarr']
Once the cube is stored in our team s3 storage, we can use xcube viewer jupyterlab extention to visualise it.
from xcube.webapi.viewer import Viewer
We use the xcube datastore framework here to open the dataset, but it could also be opened by other means, e.g., xr.open_dataset()
, provided it has variables with dimensions ["time", "y", "x"] or ["y", "x"].
dataset = team_store.open_data(output_id)
dataset
<xarray.Dataset> Size: 1GB Dimensions: (time: 7, lat: 3600, lon: 7200, bnds: 2) Coordinates: * lat (lat) float32 14kB -89.97 -89.93 -89.88 ... 89.88 89.93 89.97 lat_bnds (lat, bnds) float32 29kB dask.array<chunksize=(3600, 2), meta=np.ndarray> * lon (lon) float32 29kB -180.0 -179.9 -179.9 ... 179.9 179.9 180.0 lon_bnds (lon, bnds) float32 58kB dask.array<chunksize=(7200, 2), meta=np.ndarray> * time (time) datetime64[ns] 56B 1981-09-01T12:00:00 ... 1981-09-0... time_bnds (time, bnds) datetime64[ns] 112B dask.array<chunksize=(7, 2), meta=np.ndarray> Dimensions without coordinates: bnds Data variables: analysed_sst (time, lat, lon) float64 1GB dask.array<chunksize=(1, 1200, 2400), meta=np.ndarray> Attributes: Conventions: CF-1.7 date_created: 2024-09-18T08:07:18.447033 history: [{'cube_params': {'time_range': ['1981-09-01T00:... processing_level: L4 time_coverage_duration: P7DT0H0M0S time_coverage_end: 1981-09-08T00:00:00 time_coverage_start: 1981-09-01T00:00:00 title: esacci.SST.day.L4.SSTdepth.multi-sensor.multi-pl...
Scenario 1: Open xcube Viewer for a dataset instances persisted from a certain source (saved datasets).
For the functionalities of xcube viewer please head over to the documentation: https://xcube.readthedocs.io/en/latest/viewer.html#functionality
viewer = Viewer()
WARNING:tornado.general:404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured WARNING:tornado.general:404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured WARNING:tornado.access:404 GET /viewer/config/config.json (127.0.0.1) 4.77ms WARNING:tornado.access:404 GET /viewer/config/config.json (127.0.0.1) 4.77ms
viewer.add_dataset(dataset)
'11098dfc-54a0-4462-8de3-cc3abfd36d5f'
You can click on the viewer link to open xcube Viewer in a new browser tab:
viewer.info()
Server: https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8001 Viewer: https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8001/viewer/?serverUrl=https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8001
You can also open xcube Viewer inlined here:
viewer.show()
To stop the server and viewer:
viewer.stop_server()
Scenario 2: Open xcube Viewer for a dataset instances opened or otherwise created in this Notebook (in-memory datasets).
Below, let's fetch a dataset from CDS on the fly, without persisting it - for more details about xcube CDS datastore and how to get CDS credentials please checkout the example notebook in xcube-datastores GENERATE C3S CDS CUBES. Be aware of performance loss, so in case you plan to use a dataset a lot for analysis or visualisation, please persist it into the team s3 storage. The public cubes provided within DeepESDL are already persisted in S3, so you should not duplicate them in your team storage.
import os
os.environ['CDSAPI_URL'] = 'https://cds-beta.climate.copernicus.eu/api'
os.environ['CDSAPI_KEY'] = '[PERSONAL-ACCESS-TOKEN]'
cds_store = new_data_store('cds')
bbox=[-5, 45, 35, 65]
cds_dataset = cds_store.open_data('reanalysis-era5-single-levels-monthly-means:monthly_averaged_reanalysis',
variable_names=['2m_temperature'],
bbox=bbox,
spatial_res=0.25,
time_range=['2010-01-01', '2010-12-31'])
cds_dataset
xcube-cds version 0.9.3 2024-09-18 08:40:41,936 INFO Request ID is 6a55691a-15bb-4b7d-81dc-fedb6febd390 INFO:cads_api_client.processing:Request ID is 6a55691a-15bb-4b7d-81dc-fedb6febd390 2024-09-18 08:40:41,973 INFO status has been updated to accepted INFO:cads_api_client.processing:status has been updated to accepted 2024-09-18 08:40:43,517 INFO status has been updated to running INFO:cads_api_client.processing:status has been updated to running 2024-09-18 08:40:45,804 INFO status has been updated to successful INFO:cads_api_client.processing:status has been updated to successful
9830c36a333f3eab454e3817a76610df.nc: 0%| | 0.00/322k [00:00<?, ?B/s]
<xarray.Dataset> Size: 617kB Dimensions: (lat: 80, lon: 160, time: 12) Coordinates: number int64 8B ... * lat (lat) float64 640B 64.88 64.62 64.38 64.12 ... 45.62 45.38 45.12 * lon (lon) float64 1kB -4.875 -4.625 -4.375 -4.125 ... 34.38 34.62 34.88 expver (time) <U4 192B ... * time (time) datetime64[ns] 96B 2010-01-01 2010-02-01 ... 2010-12-01 Data variables: t2m (time, lat, lon) float32 614kB ... Attributes: GRIB_centre: ecmf GRIB_centreDescription: European Centre for Medium-Range Weather Forecasts GRIB_subCentre: 0 Conventions: CF-1.7 institution: European Centre for Medium-Range Weather Forecasts history: 2024-09-18T08:40 GRIB to CDM+CF via cfgrib-0.9.1...
cds_dataset.attrs["title"] = "ERA5 2m Temperature"
Let's set some attributes of the variable, so the colormapping does not fall back on the default
cds_dataset.t2m.attrs["color_value_min"] = 270
cds_dataset.t2m.attrs["color_value_max"] = 310
cds_dataset.t2m.attrs["color_bar_name"] = "plasma"
viewer = Viewer()
viewer.add_dataset(dataset)
viewer.add_dataset(cds_dataset)
'f6015205-89c6-49d5-a0c4-d7c90694d5b4'
You can click on the viewer link to open xcube Viewer in a new browser tab:
viewer.info()
Server: https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8006 Viewer: https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8006/viewer/?serverUrl=https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8006
You can also open xcube Viewer inlined here:
viewer.show()
To stop the server and viewer:
viewer.stop_server()
Scenario 3: Use custom server configuration to start server and pass it to the viewer constructor. In this case, we have created a local file with the configuration and load it as a dictionary and pass it to the viewer.
The custom configuration allows you to predefine your value ranges, the colormaps that should be used as well as which bands should be used to create an RGB image, then the RGB switch in the viewer will display the RGB image.
If you do not have a server-config.yaml file in your directory, please create one with the following content:
DataStores:
- Identifier: deep-esdl-cci-sst
StoreId: s3
StoreParams:
root: $S3_USER_STORAGE_BUCKET
storage_options:
anon: false
key: $S3_USER_STORAGE_KEY
secret: $S3_USER_STORAGE_SECRET
Datasets:
- Path: "*.zarr"
Style: default
# ChunkCacheSize: 1G
Styles:
- Identifier: default
ColorMappings:
analysed_sst:
ColorBar: plasma
ValueRange: [270, 310]
## if you have bands that can create an RGB image, you can specify them as below.
# rgb:
# Red:
# Variable: B04
# ValueRange: [0., 0.25]
# Green:
# Variable: B03
# ValueRange: [0., 0.25]
# Blue:
# Variable: B02
# ValueRange: [0., 0.25]
For all possible settings within the server configuration file, please checkout the documentation: https://xcube.readthedocs.io/en/latest/cli/xcube_serve.html#configuration-file
from xcube.util.config import load_configs
viewer = Viewer(server_config=load_configs("server-config.yaml"))
viewer.show()
To stop the server and viewer:
viewer.stop_server()
Afer all our testing and exploring, let's clean up the example cube :)
team_store.delete_data(output_id)