Rolling correlation cube vs center pixel (Sentinel-2 NDVI z-scores)
This guide extends the NDVI z-score workflow by computing rolling correlation between every pixel and the center pixel of the cube. The output highlights areas that move in sync with the reference location.
Steps:
- Load Sentinel-2 data and compute NDVI z-scores (same as previous recipe).
- Downsample for faster rolling statistics (optional but recommended).
- Use
rolling_corr_vs_centerto compute correlation cubes. - Visualize with Lexcube and inspect QA summaries.
import cubedynamics as cd
from cubedynamics import pipe, verbs as v
from cubedynamics.stats.correlation import rolling_corr_vs_center
from cubedynamics.utils.chunking import coarsen_and_stride
from cubedynamics.viz.qa_plots import plot_median_over_space
s2 = cd.load_sentinel2_cube(
lat=43.89,
lon=-102.18,
start="2023-06-01",
end="2024-09-30",
edge_size=1028,
resolution=10,
cloud_lt=40,
)
ndvi_z = (
pipe(s2)
| v.ndvi_from_s2()
| v.zscore(dim="time")
)
# Downsample for performance
ndvi_z_ds = coarsen_and_stride(ndvi_z, coarsen_factor=4, time_stride=2)
# Rolling correlation vs center pixel
corr_cube = rolling_corr_vs_center(
ndvi_z_ds,
window_days=90,
min_t=5,
)
# Lexcube visualization of correlation cube
corr_clip = corr_cube.clip(-1, 1)
pipe(corr_clip) | v.show_cube_lexcube(
title="Rolling correlation vs center pixel (NDVI z-scores)",
cmap="RdBu_r",
vmin=-1,
vmax=1,
)
# QA: median correlation over space
ax = plot_median_over_space(
corr_cube,
ylabel="Median correlation",
title="Median corr vs center (rolling 90 days)",
ylim=(-1, 1),
)
Use the resulting cube to identify coherent ecological zones, potential teleconnections, or areas where vegetation dynamics are decoupled from the reference site.