In [1]:
import xarray as xr
import ndpyramid
import upath
import ipywidgets
import datatree
In [2]:
path = "s3://carbonplan-data-viewer/demo/leap-10-2023/tasmax_day_ACCESS-CM2_historical_r1i1p1f1_gn.zarr"
ds = xr.open_dataset(path, engine='zarr', chunks={})
ds
Out[2]:
<xarray.Dataset> Dimensions: (lat: 600, lon: 1440, time: 73) Coordinates: * lat (lat) float64 -59.88 -59.62 -59.38 -59.12 ... 89.38 89.62 89.88 * lon (lon) float64 0.125 0.375 0.625 0.875 ... 359.1 359.4 359.6 359.9 * time (time) datetime64[ns] 1950-01-01T12:00:00 ... 1951-12-22T12:00:00 Data variables: tasmax (time, lat, lon) float32 dask.array<chunksize=(1, 600, 1440), meta=np.ndarray> Attributes: (12/19) Conventions: CF-1.7 activity: NEX-GDDP-CMIP6 cmip6_institution_id: CSIRO-ARCCSS cmip6_license: CC-BY-SA 4.0 cmip6_source_id: ACCESS-CM2 contact: Dr. Rama Nemani: rama.nemani@nasa.gov, Dr. Bridget... ... ... resolution_id: 0.25 degree scenario: historical source: BCSD title: ACCESS-CM2, r1i1p1f1, historical, global downscale... variant_label: r1i1p1f1 version: 1.0
In [3]:
ds.tasmax.isel(time=range(3)).plot(col='time', robust=True);
In [4]:
def make_pyramids(*, ds, levels:int=3, projection:str) -> str:
projections = {'mercator': 'web-mercator', 'equirectangular': 'equidistant-cylindrical'}
path = f"s3://carbonplan-data-viewer/demo/leap-10-2023/{projection}_{levels}_pyramid_tasmax_day_ACCESS-CM2_historical_r1i1p1f1_gn.zarr"
if not upath.UPath(path).exists():
dt = ndpyramid.pyramid_regrid(ds=ds, levels=levels, projection=projections[projection])
dt.to_zarr(path, consolidated=True, mode='w')
time = xr.conventions.encode_cf_variable(dt['0'].time).data.tolist()
else:
dt = datatree.open_datatree(path, engine='zarr', chunks={}, decode_times=False)
time = dt['0'].time.data.tolist()
print(path)
source = f"https://carbonplan-data-viewer.s3.amazonaws.com/demo/leap-10-2023/{projection}_{levels}_pyramid_tasmax_day_ACCESS-CM2_historical_r1i1p1f1_gn.zarr"
dims = ds.tasmax.dims
variable = "tasmax"
return {"source" : source, "dimensions" : dims, "variable" : variable, 'time': time, 'projection': projection}
In [5]:
%%time
parameters = make_pyramids(ds=ds, levels=3, projection='mercator')
s3://carbonplan-data-viewer/demo/leap-10-2023/mercator_3_pyramid_tasmax_day_ACCESS-CM2_historical_r1i1p1f1_gn.zarr CPU times: user 482 ms, sys: 62.5 ms, total: 544 ms Wall time: 7.09 s
In [6]:
import carbonplan_maps
In [7]:
map = carbonplan_maps.Widget(
source=parameters['source'],
variable=parameters['variable'],
clim=(200, 300),
selector={'time': parameters['time'][0]},
projection=parameters['projection']
)
map
Out[7]:
In [8]:
from ipywidgets import Label
def dashboard(*, map_widget, min_value, max_value, step):
clim = ipywidgets.FloatRangeSlider(min=200, max=350, description="Clim:")
opacity = ipywidgets.FloatSlider(min=0, max=1, step=0.001, description="Opacity:")
region = ipywidgets.Checkbox(description="Region")
time_widget = ipywidgets.IntSlider(min=min_value, max=max_value, step=step, description="Time:")
# Linking selector and time_widget
def update_selector(change):
map_widget.selector = {'time': change['new']}
def update_time_widget(change):
time_widget.value = change['new']['time']
time_widget.observe(update_selector, names='value')
map_widget.observe(update_time_widget, names='selector')
# Linking
ipywidgets.jslink((map_widget, "clim"), (clim, "value"))
ipywidgets.jslink((map_widget, "opacity"), (opacity, "value"))
ipywidgets.jslink((map_widget, "region"), (region, "value"))
# Reset Button
reset_button = ipywidgets.Button(description="Reset")
def on_reset_button_clicked(_):
# Reset logic here
pass
reset_button.on_click(on_reset_button_clicked)
# Layout
visual_controls = ipywidgets.HBox([opacity, clim])
time_and_region = ipywidgets.HBox([time_widget, region, reset_button])
dash = ipywidgets.VBox([
Label("Visual Controls"),
visual_controls,
Label("Time & Region"),
time_and_region,
Label("Map"),
map_widget,
])
return dash
time = parameters['time']
selector = {'time': parameters['time'][0]}
dashboard(map_widget=map, min_value=min(time), max_value=max(time), step=time[1] - time[0])
Out[8]:
In [ ]: