Skip to main content

Solar during an eclipse

The other half of the eclipse-demand story. A solar curve near sunset is already falling, so eclipse day alone just looks like a steep evening — the chart only works against the days that didn't have an eclipse in them. Here the three previous days are the control, and one collapse turns them into a baseline the interesting day can be judged against.

The chart

Two views, one toggle. Four days is the raw material: three grey evenings — 9, 10 and 11 August, each plotted forward to eclipse day's clock — and the solid one the Moon interrupted. Anomaly vs baseline collapses the grey days into their per-quarter-hour mean and redraws every curve as a distance from it: eclipse day dives to −4.34 GW at 20:15 CEST, while the grey residuals hug zero through the whole evening ramp. The empty vertical space between them is the point: sunset is the most repeatable thing a solar fleet does, and this one broke the pattern by gigawatts.

The data

Real measured data — Spain's grid-scale solar at 15-minute cadence from energy-charts.info (Fraunhofer ISE), CC BY 4.0, upstream ENTSO-E — the same source family as the German Easter-weekend fixture behind the track's first three cards. Retrieved the morning after the eclipse. Four civil days on one shared index:

ColumnMeaning
eclipseDaySolar generation on 12 August, GW — 29.67 peak
aug09aug11The three days before, shifted to the same clock time

The shift is the device, so here it is in plain words: the grey curves did not happen when the axis says — each happened one, two or three days earlier. Plotting reference series at a false time is only honest when the page says so, every time. (The Niño 3.4 card does the same thing with 45 years; this is the long-weekend version.)

The baseline is not in the fixture — it's computed in the example, and that's deliberate: it is one collapse (below), and teaching it is this card's job. Judged against it, the days have two personalities. The afternoon is weather: cloud swings individual days up to 3.57 GW from the pack's mean (at 17:00), and eclipse day itself rides above baseline from late morning until 18:30, peaking at +3.53 GW at 17:00 — it was the sunniest of the four (29.67 GW peak against the baseline's 27.22). The evening ramp is physics: from 19:45 onward the three ordinary days sit within ±0.53 GW of their mean, tightening to ±0.21 by 20:30. Into that repeatability the eclipse cuts a −4.34 GW anomaly at 20:15 — at 20:00 the gap is twelve times the ordinary envelope (−3.86 GW against ±0.31) — then fades with the daylight: −0.45 GW by 21:00, gone by 21:30. Red Eléctrica had pre-announced a loss of up to 5 GW.

One more quirk worth reading off the chart: none of the four days ever touches zero. Each enters the night around 0.5–0.65 GW and drains to 0.12–0.22 GW before dawn — ENTSO-E reports concentrated solar plants discharging stored heat after dark inside the same category as PV.

The eclipse marks are the same ECLIPSE_MARKS constants the demand card draws (IGN's Madrid circumstances) — one fixture module, two cards, one set of facts. The time axis renders in your browser's timezone; clock times here are CEST.

Build it

1. Put all four days in one series. The overlay happens in the fixture: sample i of every column is the same clock time on a different day, so one TimeSeries keyed by eclipse-day timestamps carries the whole comparison. Drawing the raw spaghetti is four <LineChart>s — the reference pack muted, the subject on top:

const days = eclipseSolar(); // eclipseDay, aug09, aug10, aug11

<Layers>
<LineChart series={days} column="aug09" axis="gw" as="muted" />
<LineChart series={days} column="aug10" axis="gw" as="muted" />
<LineChart series={days} column="aug11" axis="gw" as="muted" />
<LineChart series={days} column="eclipseDay" axis="gw" />
</Layers>;

2. Collapse the pack into a baseline. collapse runs one reducer across named columns, row by row; { append: true } keeps the inputs alongside the result. The baseline is the three ordinary days' mean, and every curve's anomaly is just another collapse against it:

const series = days
.collapse(
['aug09', 'aug10', 'aug11'],
'baseline',
(v) => (v.aug09 + v.aug10 + v.aug11) / 3,
{ append: true },
)
.collapse(
['eclipseDay', 'baseline'],
'delta',
(v) => v.eclipseDay - v.baseline,
{ append: true },
);

The example repeats the delta step for each grey day (aug09Delta, …), so the ordinary days can be drawn as residuals too — they're the envelope that tells you whether the anomaly is signal. (In the real source the mean's inputs come from the exported ECLIPSE_BASELINE_DAYS list rather than being spelled twice, so the column set has one home.)

3. Re-centre the view. The anomaly mode is the same four layers reading the delta columns, with the axis relabelled as a distance and a <Baseline> naming the new zero:

<YAxis id="gw" label="GW vs baseline" format="+.1f" width={56} />
<Layers>
<LineChart series={series} column="aug09Delta" axis="gw" as="muted" />
{/* …aug10Delta, aug11Delta… */}
<LineChart series={series} column="delta" axis="gw" />
<Baseline value={0} axis="gw" label="3-day baseline" />
</Layers>

The toggle between the two is ordinary React state — swap the column props and the axis; the pond pipeline above already carries both readings of the same data.

Options to try

OptionWhat it doesReach for it when
More baseline daysA deeper pack behind the subjectThree days is a long weekend; thirty is a climatology — see Niño 3.4
Median, not meancollapse with a different reducerA baseline that shouldn't move when one control day was cloudy
as="muted"The reference pack in the theme's neutralAny shifted or historical comparison curves
format="+.1f"Signed tick labels on the anomaly axisAny re-centred view — the sign is the reading
min={0} on YAxisPins the raw view's floor at zeroQuantities-from-zero (generation, traffic); meaningless once re-centred
curve="monotone"Smooths all the bells15-minute and coarser cadences, where the ramp shouldn't look like line segments

See also