Interpolate grid data to station data

Interpolate grid data to station data#

This example demonstrates how to interpolate 2m temperature data from a regular grid (ERA5 reanalysis data) to specific point locations (cities in Eastern China) using the easyclimate.interp.interp_mesh2point function from the easyclimate package.

The workflow includes:

  1. Loading and visualizing the grid data

  2. Creating a DataFrame with point locations

  3. Performing the interpolation

  4. Visualizing the results with interpolated values

Before proceeding with all the steps, first import some necessary libraries and packages

import easyclimate as ecl
import xarray as xr
import cartopy.crs as ccrs
import numpy as np
import pandas as pd

Load 2m temperature data from a NetCDF file (ERA5 reanalysis data) The data contains temperature values on a regular latitude-longitude grid

t2m_data = xr.open_dataset("js_t2m_ERA5_2025052000.nc").t2m
t2m_data
<xarray.DataArray 't2m' (lat: 81, lon: 121)> Size: 39kB
[9801 values with dtype=float32]
Coordinates:
    number      int64 8B ...
    valid_time  datetime64[ns] 8B ...
  * lat         (lat) float64 648B 45.0 44.75 44.5 44.25 ... 25.5 25.25 25.0
  * lon         (lon) float64 968B 100.0 100.2 100.5 100.8 ... 129.5 129.8 130.0
    expver      <U4 16B ...
Attributes: (12/32)
    GRIB_paramId:                             167
    GRIB_dataType:                            an
    GRIB_numberOfPoints:                      1038240
    GRIB_typeOfLevel:                         surface
    GRIB_stepUnits:                           1
    GRIB_stepType:                            instant
    ...                                       ...
    GRIB_totalNumber:                         0
    GRIB_units:                               K
    long_name:                                2 metre temperature
    units:                                    degC
    standard_name:                            unknown
    GRIB_surface:                             0.0


Create a basemap plot focused on Eastern China region

fig, ax = ecl.plot.quick_draw_spatial_basemap(figsize=(5, 5))
ax.set_extent([116, 123, 30, 36], crs = ccrs.PlateCarree())

# Select and plot temperature data for the region of interest
draw_data = t2m_data.sel(lon = slice(100, 140), lat = slice(45, 25))
draw_data.plot.contourf(
    ax = ax,
    transform=ccrs.PlateCarree(),
    cbar_kwargs = {'location': 'bottom'},
    levels = np.linspace(17, 29, 21),
    cmap = "plasma"
)

ax.set_title("2m temperature")
2m temperature
Text(0.5, 1.0, '2m temperature')

Create a DataFrame containing city locations (longitude and latitude) These are the points where we want to interpolate temperature values

data = {
    "Site": ["Nanjing (南京)", "Suzhou (苏州)", "Shanghai (上海)", "Chuzhou (滁州)", "Changzhou (常州)", "Xuzhou (徐州)", "Yancheng (盐城)"],
    "lon": [118.7788631, 120.6212881, 121.4700152, 118.3139455, 119.9691539, 117.1810431, 120.1577019],
    "lat": [32.0438284, 31.311123, 31.2312707, 32.3027377, 31.8122623, 34.2665258, 33.349559]
}
df = pd.DataFrame(data)
df
Site lon lat
0 Nanjing (南京) 118.778863 32.043828
1 Suzhou (苏州) 120.621288 31.311123
2 Shanghai (上海) 121.470015 31.231271
3 Chuzhou (滁州) 118.313946 32.302738
4 Changzhou (常州) 119.969154 31.812262
5 Xuzhou (徐州) 117.181043 34.266526
6 Yancheng (盐城) 120.157702 33.349559


Use interp_mesh2point to interpolate grid values to point locations Parameters:

  • t2m_data: Input grid data (xarray DataArray)

  • df: DataFrame with point locations

  • lon/lat_dim_mesh: Name of lon/lat dimensions in grid data

  • lon/lat_dim_df: Name of lon/lat columns in DataFrame

df_interp = ecl.interp.interp_mesh2point(
    t2m_data, df,
    lon_dim_mesh = "lon",
    lat_dim_mesh = "lat",
    lon_dim_df = "lon",
    lat_dim_df = "lat"
)
df_interp
Site lon lat interpolated_value
0 Nanjing (南京) 118.778863 32.043828 27.434105
1 Suzhou (苏州) 120.621288 31.311123 27.056907
2 Shanghai (上海) 121.470015 31.231271 25.860559
3 Chuzhou (滁州) 118.313946 32.302738 27.139358
4 Changzhou (常州) 119.969154 31.812262 27.489566
5 Xuzhou (徐州) 117.181043 34.266526 28.625858
6 Yancheng (盐城) 120.157702 33.349559 26.331501


Create a combined plot showing both the grid data and interpolated points

proj_trans = ccrs.PlateCarree() # Coordinate reference system for transformations

fig, ax = ecl.plot.quick_draw_spatial_basemap(figsize=(5, 5))
ax.set_extent([116, 123, 30, 36], crs = proj_trans)

draw_data = t2m_data.sel(lon = slice(100, 140), lat = slice(45, 25))

# Plot the grid data again for reference
draw_data.plot.contourf(
    ax = ax,
    transform=ccrs.PlateCarree(),
    cbar_kwargs = {'location': 'bottom'},
    levels = np.linspace(17, 29, 21),
    cmap = "plasma"
)

# Plot the point locations as red dots
ax.scatter(
    df_interp["lon"],
    df_interp["lat"],
    transform = proj_trans,
    color = 'r',
    s = 5
)

# Add temperature values as text labels near each point
for i, row in df_interp.iterrows():
    ax.text(
        row["lon"],
        row["lat"],
        str(np.round(row["interpolated_value"], decimals=2)), # Rounded to 2 decimal places
        transform=proj_trans,
        fontsize=10,
        ha='center',  # Horizontal alignment
        va='bottom',  # Vertical alignment
        color='blue'
)

ax.set_title("2m temperature (Points)")
2m temperature (Points)
Text(0.5, 1.0, '2m temperature (Points)')

Total running time of the script: (0 minutes 0.785 seconds)