Interactive plots with Ipyleaflet
Overview:¶
- Interactively display images from remote map servers with ipyleaflet
- Overlay gridded data on the interactive map
Imports¶
from datetime import datetime, timedelta
from ipyleaflet import Map, TileLayer, basemaps, basemap_to_tiles
from ipyleaflet.velocity import Velocity
import xarray as xrInteractively display images from remote map servers with ipyleaflet¶
While we’ve made some nice looking maps so far in the course, they are all static images ... i.e., they can only be viewed ... not interacted with. Most of us have browsed interactive map-based websites, such as Google Maps, where we can use our mouse or touch-enabled screen to move around, zoom in or out, or otherwise intereact with the plot. The Javascript programming language is what makes this interactivity possible. Here, we will use a Python package, ipyleaflet, as a “bridge” to Javascript.
Use a satellite composite as the base image.¶
Now, specify an image tile server and product, using the same sources as those provided by Contextily, which we’ll cover in some upcoming notebooks.. Center the map and specify a zoom level.
Create time strings¶
We’ll need to select a date and time, and then pass in date/time objects or strings to various functions below; their format will be function-specific.
timeObj = datetime(2025,10,16,12)
timeStr1 = timeObj.strftime("%Y-%m-%d")
timeStr2 = timeObj.strftime("%Y%m%d_%H%M")timeStr2'20251016_1200'm = Map(
basemap=basemap_to_tiles(basemaps.NASAGIBS.ModisTerraTrueColorCR, timeStr1),
center=(40, -70),
zoom=4
)
mAdd a background cartographic layer.¶
We’ll use ipyleaflet’s add_layer method. We simply add another remote tile server. The default opacity is 1.0, so reduce that a bit so we still see the satellite layer.
basemapLayer = basemap_to_tiles(basemaps.CartoDB.Positron,opacity=0.5)
m.add_layer(basemapLayer)Interact with the dynamic map¶
Zoom in and out with the +/- buttons to see both layers dynamically update.
Overlay gridded data on the interactive map¶
We will display an animated wind velocity flow field, a la https://
DataArray objects so we will exploit that here.Read in a dataset based on the 0.5-degree resolution GFS on a given date and time.
ds = xr.open_dataset('https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_0p5deg_ana/GFS_Global_0p5deg_ana_'+ timeStr2 +'.grib2')Examine the dataset
dsSpecify an analysis time, and then create DataArray objects that are subset for the specified time and the 20m AGL level (this is the lowest level in the dataset)
u = ds['u-component_of_wind_height_above_ground'].sel(time=timeObj,height_above_ground1=20)
v = ds['v-component_of_wind_height_above_ground'].sel(time=timeObj,height_above_ground1=20)Create a Dataset that contains just the wind components¶
ipyleaflet’s Velocity method produces an animated streamline effect. It accepts an Xarray dataset that contains just two arrays ... specifically, the u- and v- components of the wind vector we have chosen for visualization.
(Perhaps there is a more efficient way of doing this, but the following cell will create a new Xarray Dataset that consists of just two arrays ... u and v.)
# First create the Dataset out of the 'u' Dataarray
dsWind = u.to_dataset()
# Append v to the Dataset
dsWind['v'] = v
# Rename the u DataArray to 'u'
name_dict = {'u-component_of_wind_height_above_ground':'u'}
dsWind = dsWind.rename_vars(name_dict)
# Verify that the Dataset looks ok
dsWindCreate the animation¶
Center it, specify a zoom level, and select a background map; create and add a velocity layer from the Dataset that contains u and v.
center = (43, -69)
zoom = 6
m = Map(center=center, zoom=zoom, interpolation='nearest', basemap=basemaps.CartoDB.DarkMatter)
display_options = {
'velocityType': 'Global Wind',
'displayPosition': 'bottomleft',
'displayEmptyString': 'No wind data'
}
wind = Velocity(data=dsWind,
zonal_speed='u',
meridional_speed='v',
latitude_dimension='lat',
longitude_dimension='lon',
velocity_scale=0.01,
max_velocity=120,
display_options=display_options)
m.add_layer(wind)Display the map.¶
mIf you move your mouse/touchpad, you will see direction and speed at the nearest gridpoint displayed at the bottom left of the frame.
Create a velocity map using gridded data from a different vertical level (e.g., 250 hPa); another source ... such as our realtime ECMWF / GFS in
/data7, an ERA5 Zarr store, or another datasource from the Unidata THREDDS Server.Make this notebook dynamic in terms of date so it will always provide a recent (e.g. one day ago) visualization.
Summary¶
- Ipyleaflet provides Javascript-enabled interactivity in a Jupyter notebook.
- Ipyleaflet’s
Velocityfunction creates a flow-vector field that can be layered onto a basemap. - The
Velocityfunction accepts an Xarray dataset that contains the u- and v- wind components.
What’s Next?¶
We’ll explore some GIS terminology ... rasters and vectors. We’ll continue to explore interactive visualizations, next with the Holoviz suite of packages.