Interactive Dashboard for ExtremeDT Weather Forecast Data with xcube
This notebook guides users through accessing ExtremeDT weather data cubes, filtering them by region, converting units, and visualizing the results in an interactive dashboard using the xcube viewer.
Create a dashboard based on Data Cube populated with data obtained from Weather and Geophysical Extremes Digital Twin (DT) - ExtremeDT¶
DISCLAIMER
In order to deal with the code provided within this notebook, it is required to run it on user environment (local one or virtual machine).
This notebook covers:
find available data cubes and their urls
filter data area of interest
create interactive dashboard using xcube - xviewer
Presequites
Xcube Install xcube and create a new environment
mamba create --name xcube --channel conda-forge xcube
OR
Install xcube in the current environmentmamba install --channel conda-forge xcube
Xarray
pippip install xarray
OR
condaconda install -c conda-forge xarray dask netCDF4 bottleneck
Prepre your environment¶
from xcube.webapi.viewer import Viewer
import xarray as xr
import requests
Connect with Extreme DT data cube¶
The data cube provides data:
Four variables
2t - Air temperature at 2 meteres above grond [K]
2d - Dew point temperature at 2 meteres above grond [K]
sp - Surface pressure [Pa]
Forecast 2024.04.04-13 + 96 hours for each date
Hourly step
World
Select proper data cube¶
Data cubes on s3 bucket are stored under URL https://
Data cubes are stored in two directories:
ExtremeDT - the newest one
archive - from preicus days
File nameing convention:
dt_extreme_YYYYMMDD.zarr/
YYYYMMDD - is the date when forecast starts (step 0)
Results
After exectution of code below, the list of urls linked to available cubes will be printed.
# URL to s3 where ExtremeDT data cubes are stored
datacube_url = 'https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube'
response = requests.get(datacube_url)
if response.status_code == 200:
lines = response.text.splitlines()
zarr_items = [line for line in lines if line.endswith('.zarr') or line.endswith('.zarr/')]
if zarr_items:
for item in zarr_items:
print(item)
new_url = f"{datacube_url}/{item}"
print("New URL:", new_url)
else:
print("No .zarr files or directories found.")
else:
print("Failed to fetch contents. Status code:", response.status_code)
ExtremeDT/dt_extreme_20240404.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240404.zarr/
ExtremeDT/dt_extreme_20240405.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240405.zarr/
ExtremeDT/dt_extreme_20240406.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240406.zarr/
ExtremeDT/dt_extreme_20240407.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240407.zarr/
ExtremeDT/dt_extreme_20240408.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240408.zarr/
ExtremeDT/dt_extreme_20240410.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240410.zarr/
ExtremeDT/dt_extreme_20240411.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240411.zarr/
ExtremeDT/dt_extreme_20240412.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240412.zarr/
ExtremeDT/dt_extreme_20240413.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/ExtremeDT/dt_extreme_20240413.zarr/
archive/dt_extreme_20240409.zarr/
New URL: https://s3.central.data.destination-earth.eu/swift/v1/dedl_datacube/archive/dt_extreme_20240409.zarr/
url = 'https://s3.waw3-1.cloudferro.com/swift/v1/s5p_l3/ExtremeDT/dt_extreme_20240412.zarr/'
Area of interest¶
Upload data for selected area and verify what variables are provided. In this case uplaod data for Kenya. List of available variables should be returend.
kenya_bbox = [33.501, # West
-4.677, # South
41.899, # East
5.193] # North
kenya_dt = xr.open_zarr(url).sel(lon=slice(kenya_bbox[0],
kenya_bbox[2]),
lat=slice(kenya_bbox[3],
kenya_bbox[1]),
)
list(kenya_dt.keys())
['2d', '2t', 'sp']
Prepare Data for visualization¶
Convert units¶
kenya_dt['2t'] -= 273.15 # Conversion to Celcius degrees
kenya_dt['2d'] -= 273.15 # Conversion to Celcius degrees
kenya_dt['sp'] /= 100 # Conversion to hectoPascals
kenya_dt['2t'].attrs['units'] = '°C'
kenya_dt['2d'].attrs['units'] = '°C'
kenya_dt['sp'].attrs['units'] = 'hPa'
Define style of visualization¶
Error message starting with:
404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured
404 GET /viewer/config/config.json (127.0.0.1) 2.14ms
could occur.
It is normal and does not affect on proper functioning of xviewer.
viewer = Viewer(server_config={
"Styles": [
{
"Identifier": "dt_legend", # Style's name
"ColorMappings": {
"2t": { # Variable's name
"ValueRange": [10, 30], # Variable's values range
"ColorBar": "coolwarm" # colorbar
},
"2d": { # Variable's name
"ValueRange": [0, 20],
"ColorBar": "coolwarm",
},
'sp': { # Variable's name
"ValueRange": [0, 1000], # Variable's values range
"ColorBar": "viridis" # colorbar
},
}
},
]
})
404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured
404 GET /viewer/config/config.json (127.0.0.1) 2.14ms
/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/core/schema.py:464: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
dim_name: cube_chunks.get(dim_name, cube.dims[dim_name])
/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/core/timecoord.py:248: FutureWarning: 'S' is deprecated and will be removed in a future version, please use 's' instead.
return getattr(timestamp, round_fn)(freq).isoformat() + 'Z'
404 GET /favicon.ico (127.0.0.1) 0.52ms
404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured
404 GET /viewer/config/config.json (127.0.0.1) 1.51ms
/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/core/timecoord.py:248: FutureWarning: 'S' is deprecated and will be removed in a future version, please use 's' instead.
return getattr(timestamp, round_fn)(freq).isoformat() + 'Z'
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/64/77?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/64/77?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/63/77?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/63/77?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/64/76?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/64/76?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/63/78?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/63/78?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/64/78?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/64/78?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/63/76?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/63/76?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/65/75?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/65/75?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception GET /tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/62/75?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='GET', uri='/tiles/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d/7/62/75?crs=EPSG%3A3857&vmin=0&vmax=20&cbar=coolwarm&time=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 354, in get
await self._call_method('get', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 139, in get
await super().get(datasetId, varName, z, y, x)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/tiles/routes.py", line 125, in get
await self.response.finish(tile)
tornado.iostream.StreamClosedError: Stream is closed
Uncaught exception POST /timeseries/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d?aggMethods=mean%2Cstd&startDate=2024-04-12T00%3A00%3A00Z&endDate=2024-04-15T23%3A00%3A00Z (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8002', method='POST', uri='/timeseries/ba3aaa64-1bdf-425d-8458-98b819c0e042/2d?aggMethods=mean%2Cstd&startDate=2024-04-12T00%3A00%3A00Z&endDate=2024-04-15T23%3A00%3A00Z', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/tornado/web.py", line 1790, in _execute
result = await result
^^^^^^^^^^^^
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 357, in post
await self._call_method('post', *args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/server/webservers/tornado.py", line 372, in _call_method
await method(*args, **kwargs)
File "/home/patryk/miniconda3/envs/xcube_env/lib/python3.12/site-packages/xcube/webapi/timeseries/routes.py", line 122, in post
await self.response.finish(dict(result=result))
tornado.iostream.StreamClosedError: Stream is closed
Add style to the data cube¶
viewer.add_dataset(kenya_dt,
style="dt_legend")
'ba3aaa64-1bdf-425d-8458-98b819c0e042'
Run the dashboard¶
viewer.info() # open dashboard in separate tab in browser
#viewer.show() # open dashboard in current Jupyter Notebook
Server: http://localhost:8002
Viewer: http://localhost:8002/viewer/?serverUrl=http://localhost:8002