Berlin in Green

Monthly NDVI across Berlin

BERLIN IS GREEN

Monthly NDVI across Berlin from Sentinel-2, 2025 — a common colour scale reveals the real seasonal rhythm of vegetation.

The boxplot below summarises every pixel in Berlin for each month: the box spans the interquartile range, the line marks the median, and the whiskers trace the spread. Read left to right, it is the seasonal cycle in a single frame — the winter floor, the spring climb, the summer plateau and the autumn descent.

How this was made

The measure behind every map is the Normalised Difference Vegetation Index (NDVI), computed from the red and near-infrared bands of Sentinel-2 (Copernicus Surface Reflectance, harmonised). The index is defined as NDVI = (NIR − Red) / (NIR + Red), a normalised ratio that always falls between −1 and +1. Healthy, actively growing vegetation reflects strongly in the near-infrared while its chlorophyll absorbs red light, so NDVI rises toward 1 where canopies are dense and vigorous, and falls toward 0 over bare soil, sealed surfaces and dormant vegetation. Water, cloud and snow typically return negative values.

Doing it in R with rgee and terra

The workflow splits cleanly in two. The NDVI itself is computed in the cloud through rgee, the R interface to Google Earth Engine: the Sentinel-2 harmonised collection is filtered to Berlin and to the period of interest, screened for cloud, reduced to a single median NDVI composite, and that finished raster is exported and pulled down to the local session. Earth Engine does the heavy lifting over the full scene archive; what comes back is one clean NDVI surface for the city.

From there the analysis stays entirely in R with terra. The downloaded NDVI raster is read in and summarised over Berlin as a whole — both the median, robust to outliers, and the mean — giving a city-wide measure of NDVI for the period.

To break that figure down by district, the Bezirke boundaries are taken from Berlin’s open-data portal and read in with sf as vector polygons. With the boundaries and raster aligned to a common projection, terra computes zonal statistics — the median and mean NDVI within each of the twelve Bezirke — and the resulting values are joined back onto the sf object, so each district polygon carries its own NDVI summary ready to map.

The visualization

The maps and charts themselves are drawn with ggplot2, using its spatial geometry to render both the continuous NDVI raster and the district polygons within a single grammar of graphics. ggspatial adds the cartographic furniture — a north arrow, a scale bar, and basemap handling — that turns a plot into a readable map, while a carefully chosen colour scale carries the NDVI gradient from bare, sealed ground through to dense canopy. The per-district figures drive the choropleths and comparison charts: each Bezirk coloured and ranked by its NDVI, so the contrast between the green outer districts and the sealed inner city reads directly off the map.

The page you are reading is built with Quarto, which weaves the narrative text, the R code and its rendered outputs into a single reproducible document. Every map, chart and figure is generated at render time by the code embedded in the source, so the whole chain — from Sentinel-2 archive through terra and ggplot2 to the finished web page — runs end to end from one compact, self-contained project.

Sources: Copernicus – ESA · Sentinel-2 SR Harmonized
Software: R · Quarto · Closeread
Made by K. Wiese