Portrait of Toni Nestorowicz

Toni Nestorowicz

Data scientist, driven by curiosity and a simple belief: anything can be improved. Right now I apply it to defect detection in manufacturing, using conventional and AI-driven computer vision to reduce production stops.

Outside work I run races, sometimes onto the podium, and cycle a lot. Below are two things I care about, as data: the climate and my training.

Email: my first name at this domainLinkedIn

The longer you look, the clearer it gets

Each of the 6,786 tiles is one stretch of ten years or more in the De Bilt temperature record, sitting above the years it spans: warm colours if it warmed, blue if it cooled, stronger for faster change.

Short stretches go both ways: of the 116 ten-year stretches, 72 warmed and 44 cooled, but only 4 by more than the year-to-year noise. Above the dashed line, at 46 years or more, none cooled. The warming has also sped up: the 46 years to 2025 warmed almost three times as fast as the 46 years to 1960.

Point at a tile to see its years; click to keep it, and click it again to let go.Tap a tile, or drag across the triangle: sideways moves the stretch through time, up and down changes its length. Tap outside it to let go.

How this was made

Data. Daily mean temperature at De Bilt, one of the five principal stations in KNMI’s homogenised temperature dataset (version 2, 2026), averaged over each complete year from 1901 to 2025.

Tiles. Each tile is the least-squares trend of one stretch. It sits above the middle of its years, one row higher for each extra year, so every stretch lies above the shorter stretches it contains. Colour runs from grey at no change to the strongest red or blue at 0.7 °C per decade or more. The bars below show each year against the 1901–2025 average. Computing the trend of every possible period is an established technique in climate and hydrology research (Liebmann et al., 2010, doi:10.1175/2010BAMS3030.1; Hannaford et al., 2013, doi:10.5194/hess-17-2717-2013).

Uncertainty. The switch under the figure fades every stretch whose 95% interval for the trend includes zero. The interval is widened for the slight persistence from one year to the next (lag-1 autocorrelation 0.13), using the effective sample size of Santer et al. (2008, doi:10.1002/joc.1756). For 96% of stretches shorter than 20 years it includes zero, so their colour reflects noise as much as climate. Overlapping stretches share most of their years, so the fade is a guide rather than a formal test.

Limits. This is one station, and the uncertainty of the homogenisation is not shown. KNMI deliberately does not correct for gradual changes around the station, such as urbanisation. The 46-year threshold is a knife edge: the longest cooling stretch, 1943 to 1987, cooled by 0.02 °C per decade, and the weakest 46-year stretch warmed by less than 0.01. The figure shows how the temperature changed, not why.

Reproduce the figure and every number above with one script; it needs only uv.

git clone \
  https://github.com/professional-cynic/nestorowicz.nl
cd nestorowicz.nl/climate
./triangle.py

Next: how my training branched outRead my CV

How my training branched out

One branch per sport, sprouting at my first session. Each hair is a week: the longer, the more hours.

Winter, December to February

Did you notice? From December to February, most of my cycling happens indoors. And the walking branch is thick because I love walking: it is my cross-training.

Point along the branches to read any week.Drag sideways across the branches to read any week.

Year by year

How this was made

Data. My own Strava export, reduced to the local date, sport and moving time of each session since 2018, plus the distance of runs over 1 km and outdoor rides over 5 km. Indoor distances are simulated, so they are left out.

Branches. Each hair is the moving time of one week, Monday to Sunday, mirrored around the stem, and all branches share one scale, so their thickness can be compared directly. A branch leaves the cycling stem at the date of its first session: it marks when a sport started, not that it grew out of cycling.

Charts. Calendar years, from the first complete one; the hollow point is this year so far. Pace is total moving time divided by total distance; speed is total distance divided by total moving time.

Limits. Only what I recorded counts. Moving time leaves out stops, and a week with no session may be a rest week or a week I forgot to record.

Reproduce. The page carries sessions.csv inside it and computes every number from it, so the sentences stay true when the data is rebuilt. The sanitising script turns a Strava bulk export into that file and writes it into the page.

cd nestorowicz.nl/sport
./sanitise_strava.py activities.csv \
  sessions.csv --embed ../index.html

The layout borrows from spindle diagrams in palaeontology and from Tufte’s small multiples.

Back to the climateRead my CV