Vector data resampling - subsampling

This section explores subsampling (also known as thinning) of vector data. Subsampling reduces the number of points plotted, which is especially useful when visualising vector fields such as wind. It helps prevent overcrowding of arrows or flags and ensures consistent visual density across different projections.

Example: Wind from Storm Ophelia (October 2017)

In this example, we will use sample wind data from Storm Ophelia, which impacted the UK in October 2017.

[1]:
import earthkit.data as ekd

import earthkit.plots as ekp

data = ekd.from_source("sample", "storm_ophelia_wind_850.grib").to_fieldlist()
data.ls()
[1]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 u 2017-10-16 2017-10-16 0 days 850 pressure 0 regular_ll
1 v 2017-10-16 2017-10-16 0 days 850 pressure 0 regular_ll

Subsampling with Subsample

To subsample our vector points, we can use the Subsample class from earthkit.plots.resample.

Subsample Modes

Subsample offers two modes:

  • stride: Selects points based on a regular step (stride) in x and y.

  • fixed: Selects a fixed number of points in x and y, distributed evenly across the plot.

Subsampling with mode="stride"

Using mode="stride", you can specify the step size of your subsample. For example, striding with a value of 1 samples every grid cell. Let’s plot the wind U component grid cells alongside our vector data to see how the spacing changes with different subsamples.

[2]:
from earthkit.plots.resample import Subsample

# Create a map of the region around the UK
chart = ekp.Map(domain=[-20, 5, 40, 60])

# Plot the original grid cells of the wind U component
chart.grid_cells(data[0], alpha=0.5)

# Plot wind arrows at every grid cell
chart.quiver(data, resample=Subsample(1, mode="stride"))

# Add map features
chart.coastlines(color="white", linewidth=2)
chart.gridlines()

# Show the plot
chart.show()
../../../_images/examples_examples_vectors_vectors-subsampling_3_0.png

Different strides in x and y

You can also specify different strides for x and y with the nx and ny arguments. Let’s do that now with a step of 3 in x and 2 in y - you can see that every third grid cell in the x direction is sampled, and every second grid cell in y.

[3]:
# Create a map of the region around the UK
chart = ekp.Map(domain=[-20, 5, 40, 60])

# Plot the original grid cells of the wind U component
chart.grid_cells(data[0], alpha=0.5)

# Plot wind arrows at every third x point and every second y point
chart.quiver(data, resample=Subsample(nx=3, ny=2, mode="stride"))

# Add map features
chart.coastlines(color="white", linewidth=2)
chart.gridlines()

# Show the plot
chart.show()
../../../_images/examples_examples_vectors_vectors-subsampling_5_0.png

Subsampling with mode="fixed"

In fixed mode, you specify the desired number of points in x (nx) and y (ny). The points are evenly distributed over the plot.

For example, let’s resample the vector data to 20 points in x and 20 points in y:

NOTE: mode=”fixed” provides an approximate number of points. The exact number may vary:

  • If nx or ny exceeds the dataset’s resolution, the plot will show the full resolution, and never interpolate to a higher resolution (use earthkit.plots.resample.Bilinear for this, which is covered in the next section).

  • The sampling is always evenly spaced, ensuring a uniform distribution. This means that if nx or ny is not a factor of the number of x or y points in your data, you will get a number of points equal to the nearest factor.

[4]:
# Create a map of the region around the UK
chart = ekp.Map(domain=[-20, 5, 40, 60])

# Plot the original grid cells of the wind U component
chart.grid_cells(data[0], alpha=0.5)


# Plot wind arrows with a density of 20 in x and 20 in y
chart.quiver(data, resample=Subsample(nx=20, ny=20, mode="fixed"))

# Add map features
chart.coastlines(color="white", linewidth=2)
chart.gridlines()

# Show the plot
chart.show()
../../../_images/examples_examples_vectors_vectors-subsampling_8_0.png