diff --git a/intermediate/xarray_ecosystem.ipynb b/intermediate/xarray_ecosystem.ipynb index 0a313bcf..7f7802c9 100644 --- a/intermediate/xarray_ecosystem.ipynb +++ b/intermediate/xarray_ecosystem.ipynb @@ -130,7 +130,33 @@ "metadata": {}, "source": [ "## Rioxarray via the backend entrypoint\n", - "more details about rioxarray here" + "\n", + "[Rioxarray](https://corteva.github.io/rioxarray/stable/index.html) is a Python library that enhances Xarray's ability to work with geospatial data and coordinate reference systems. Geographic information systems use GeoTIFF and [many other formats](https://gdal.org/drivers/raster/index.html) to organize and store gridded, or *raster*, datasets. \n", + "\n", + "The Geospatial Data Abstraction Library ([GDAL](https://gdal.org)) provides foundational drivers and geospatial algorithms, and the [rasterio](https://rasterio.readthedocs.io/en/latest) library provides a Pythonic interface to GDAL. `Rioxarray` brings key features of rasterio to Xarray:\n", + "\n", + "1. A backend *engine* to read any format recognized by *GDAL*\n", + "1. A `.rio` *accessor* for *rasterio's* geospatial algorithms such as reprojection\n", + "\n", + "Below a couple brief examples to illustrate these features:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import rioxarray # ensure you have rioxarray installed in your environment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can explicitly use rioxarray's 'rasterio' engine to load myriad geospatial raster formats, below is a [Cloud-Optimized Geotiff](https://www.cogeo.org) from an AWS [public dataset](https://registry.opendata.aws/sentinel-1-rtc-indigo/) of synthetic aperture radar data over Washington, State, USA. `overview_level=4` is an argument specific to the `rasterio` engine that allows opening a pre-computed lower resolution \"overview\" of the data." ] }, { @@ -139,18 +165,67 @@ "metadata": {}, "outputs": [], "source": [ - "import rioxarray # this activates the rio accessor" + "url = 'https://sentinel-s1-rtc-indigo.s3.us-west-2.amazonaws.com/tiles/RTC/1/IW/10/U/CU/2017/S1A_20170101_10UCU_ASC/Gamma0_VV.tif'\n", + "da = xr.open_dataarray(url, engine='rasterio', open_kwargs={\"overview_level\": 2})\n", + "da" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `spatial_ref` coordinate is added by rioxarray to store standardized geospatial Coordinate Reference System (CRS) information, we can access that information and additional methods via the `.rio` accessor:" ] }, { "cell_type": "code", "execution_count": null, - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ - "# rioxarray example" + "da.rio.crs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "EPSG refers to 'European Petroleum Survey Group' a database of the many CRS definitions for our Planet used over the years! EPSG=32610 is the [\"UTM 10N\" CRS](https://epsg.io/32610), with coordinate units in meters. Let's say you want longitude,latitude coordinate points in degrees instead. You'd have to *reproject* this data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "da_lonlat = da.rio.reproject('epsg:4326')\n", + "da_lonlat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that that the size of the data has changed as well as the coordinate values. This is typical of reprojection, your data must be resampled and often interpolated to match the new CRS grid! A quick plot will compare the results of our reprojected data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import panel as pn\n", + "\n", + "img1 = da.sel(band=1).hvplot.image(\n", + " x='x', y='y', rasterize=True, cmap='gray', clim=(0, 0.5), title='UTM'\n", + ")\n", + "img2 = da_lonlat.sel(band=1).hvplot.image(\n", + " rasterize=True, cmap='gray', clim=(0, 0.5), title='LON/LAT'\n", + ")\n", + "\n", + "pn.Column(img1, img2)" ] }, { @@ -387,7 +462,7 @@ "outputs": [], "source": [ "# to be able to read unit attributes following the CF conventions\n", - "import cf_xarray.units # must be imported before pint_xarray\n", + "import cf_xarray.units\n", "import pint_xarray\n", "\n", "xr.set_options(display_expand_data=False)" @@ -496,7 +571,7 @@ "metadata": {}, "outputs": [], "source": [ - "quantified_air[\"air\"].isel(time=500).plot()" + "quantified_air[\"air\"].isel(time=500).plot();" ] }, {