Copyright CNES

Read and plot a SWOT-HR Raster products

In this notebook, we show how to read the SWOT-HR raster 100m and 250m netcdf products with xarray and how to represent a variable on a map with cartopy.

Libraries

Please note that apart from the libraries listed in the cell below, you need to install the h5netcdf library (conda install -c conda-forge h5netcdf). This will be used by th xarray.open_dataset function to read the netcdf files.

[1]:
import xarray as xr
import rioxarray
from pyproj import CRS
import os
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

1. Read a SWOT-HR Raster netcdf product with xarray

[2]:
dir_swot = "../docs/data/swot/"
file_swot_raster100 = os.path.join(
    dir_swot,
    "SWOT_L2_HR_Raster_100m",
    "SWOT_L2_HR_Raster_100m_UTM22N_N_x_x_x_015_033_082F_20240509T115817_20240509T115835_PIC0_01_extract.nc",
)
# read data with xarray
xr_swot_raster100 = xr.open_dataset(file_swot_raster100)
# force xarray to acknowledge the CRS
xr_swot_raster100.rio.set_crs(CRS.from_user_input(xr_swot_raster100.crs.projected_crs_name).to_epsg(), inplace=True)

xr_swot_raster100
[2]:
<xarray.Dataset>
Dimensions:                  (y: 75, x: 59)
Coordinates:
  * x                        (x) float64 2.712e+05 2.713e+05 ... 2.77e+05
  * y                        (y) float64 5.558e+05 5.559e+05 ... 5.632e+05
Data variables: (12/39)
    cross_track              (y, x) float32 ...
    crs                      object ...
    dark_frac                (y, x) float32 ...
    geoid                    (y, x) float32 ...
    height_cor_xover         (y, x) float32 ...
    ice_clim_flag            (y, x) float32 ...
    ...                       ...
    water_frac               (y, x) float32 ...
    water_frac_uncert        (y, x) float32 ...
    wse                      (y, x) float32 ...
    wse_qual                 (y, x) float32 ...
    wse_qual_bitwise         (y, x) float64 ...
    wse_uncert               (y, x) float32 ...
Attributes: (12/50)
    Conventions:                   CF-1.7
    title:                         Level 2 KaRIn High Rate Raster Data Product
    source:                        Ka-band radar interferometer
    history:                       Wed Jun  5 21:08:21 2024: ncks -d x,271195...
    platform:                      SWOT
    references:                    V1.2.1
    ...                            ...
    x_max:                         315500.0
    y_min:                         497300.0
    y_max:                         643000.0
    institution:                   CNES
    product_version:               01
    NCO:                           netCDF Operators version 5.0.6 (Homepage =...

Should you want to quickly see what the data looks like, just use the following line. Lower in the notebook we will try to have something fancier.

[3]:
xr_swot_raster100.wse.plot(cmap='cividis')
[3]:
<matplotlib.collections.QuadMesh at 0x7fb7e41fe350>
../../_images/SWOT-Hydrology_BASIC_Read_SWOT_Raster_6_1.png

2. Plot data on maps with cartopy

[4]:
import cartopy.crs as ccrs
import cartopy.feature as cfeature


def customize_map(ax, cb, label, crs=ccrs.PlateCarree()):
    """This function customizes a map with projection and returns the plt.axes instance"""

    ax.gridlines(
        crs=crs,
        draw_labels=True,
        color='.7',
        alpha=.6,
        linewidth=.4,
        linestyle='-',
        )

    # add a background_map (default, local image, WMTS...read the doc)
    # ax.stock_img()

    # add a labeled colorbar
    plt.colorbar(
        cb,
        ax=ax,
        orientation='horizontal',
        shrink=0.6,
        pad=.05,
        aspect=40,
        label=label)

    return ax

# Create meshgrid from data
#x, y = np.meshgrid(xr_swot_raster100.longitude, xr_swot_raster100.latitude)

# 0. Create Figure and Axes
crs = ccrs.PlateCarree()
fig, axs = plt.subplots(
    nrows=1,ncols=2,
    subplot_kw={'projection': crs},
    figsize=(16,9),
    frameon=True,
    )

# 1. plot Water Surface Elevation on map
# plot data on the map with pcolor function
cb0 = axs[0].pcolor(
    xr_swot_raster100.longitude,
    xr_swot_raster100.latitude,
    xr_swot_raster100.wse,
    transform=crs,
    cmap='cividis',
    )
# customize plot with pre-defined function
customize_map(axs[0], cb0, "Water Surface Elevation (m)")

# 2. plot Water Fraction on map
cb1 = axs[1].pcolor(
    xr_swot_raster100.longitude,
    xr_swot_raster100.latitude,
    xr_swot_raster100.water_frac*100,
    transform=crs,
    cmap='BuPu',
    vmin=0,
    vmax=100,
    )
# customize plot with pre-defined function
customize_map(axs[1], cb1, "Water Fraction (%)")

/tmp/ipykernel_160234/2149712467.py:21: MatplotlibDeprecationWarning: Getting the array from a PolyQuadMesh will return the full array in the future (uncompressed). To get this behavior now set the PolyQuadMesh with a 2D array .set_array(data2d).
  plt.colorbar(
/tmp/ipykernel_160234/2149712467.py:21: MatplotlibDeprecationWarning: Getting the array from a PolyQuadMesh will return the full array in the future (uncompressed). To get this behavior now set the PolyQuadMesh with a 2D array .set_array(data2d).
  plt.colorbar(
[4]:
<GeoAxes: >
../../_images/SWOT-Hydrology_BASIC_Read_SWOT_Raster_8_2.png