MZQMohd Zamin Quadri
All work

Weather exploratory analysis

Checking an Analysis Against Its Own Generator

A weather analysis that checks itself.

Role
Author
Classification
Synthetic demonstration
Inspect repository
How far each recovered statistic landed from the value the generator was configured with. Temperature scatters around zero; humidity misses the same way in every city.Two zero-centred axes, each testing a statistic the exploratory analysis recovered against the value its generator was configured with. On the temperature axis the six cities scatter either side of zero, none of them further out than 0.09 degrees, which is what recovering a configured value looks like. A second axis then opens for humidity and its six marks all land on the same side of zero, between 2.20 and 2.53 points high - the same direction for every city, which is a bias rather than noise and is the only finding in the project that was not put there by hand. A ranking check follows, joining the cities ordered by configured seasonal swing to the same cities ordered by recovered spread, and the order is preserved. The sequence closes by naming what the whole exercise rests on: 21,900 generated records at a fixed seed, so what it can establish is that the analysis reads its own input correctly, and nothing about any real city.
  1. Problem

    Charts of synthetic data look like findings.

  2. How it was solved

    I compared what the analysis recovered with what was planted.

    1. Generate
    2. Analyse
    3. Compare
  3. Result

    0.09 °C

    largest error across six cities

  4. Built with

    • Python
    • pandas
    • matplotlib
    • seaborn
    See the evidence on GitHub
Two zero-centred axes, each testing a statistic the exploratory analysis recovered against the value its generator was configured with. On the temperature axis the six cities scatter either side of zero, none of them further out than 0.09 degrees, which is what recovering a configured value looks like. A second axis then opens for humidity and its six marks all land on the same side of zero, between 2.20 and 2.53 points high - the same direction for every city, which is a bias rather than noise and is the only finding in the project that was not put there by hand. A ranking check follows, joining the cities ordered by configured seasonal swing to the same cities ordered by recovered spread, and the order is preserved. The sequence closes by naming what the whole exercise rests on: 21,900 generated records at a fixed seed, so what it can establish is that the analysis reads its own input correctly, and nothing about any real city.

Synthetic demonstration / Exploratory analysis

Every number in this project was generated, so nothing it finds is evidence about weather. What can an exploratory analysis of invented data honestly be held to - and what does it catch when you do?

Temperature, set against recoveredwithin 0.09 °C

Invented data, and the one thing it can still be checked against

against the configured valuesSeeded generator21,900 daily records for sixcities, at a fixed seed.Seasons reversedFor the southern cities -applied in the generator and…Per-city summaryTracked as an artefact ratherthan printed and lost.Four figure familiesDistributions, seasonalcomparisons, exceedance…Recovered against configuredEvery statistic compared withthe number it was generated…What the check caughtTemperature scatters aroundzero. Humidity misses the same…
Nothing here is evidence about weather. What it can be held to is its own generator: every recovered statistic has a configured value behind it, which is what the return path compares.

This diagram in words

  1. Seeded generator source — 21,900 daily records for six cities, at a fixed seed.
  2. Seasons reversed process — For the southern cities - applied in the generator and again in the comparison.
  3. Per-city summary store — Tracked as an artefact rather than printed and lost.
    pandas
  4. Four figure families artifact — Distributions, seasonal comparisons, exceedance curves, correlations.
    matplotlib · seaborn
  5. Recovered against configured gate — Every statistic compared with the number it was generated from.
    NumPy
  6. What the check caught artifact — Temperature scatters around zero. Humidity misses the same way in every city.

01 / 7Six cities, ten yearsEvery figure the analysis reports can be checked against the value its generator was set to.

Cities
6
Years
10
Checkable because
The generator's configuration is in the repository
Two zero-centred axes, each testing a statistic the exploratory analysis recovered against the value its generator was configured with. On the temperature axis the six cities scatter either side of zero, none of them further out than 0.09 degrees, which is what recovering a configured value looks like. A second axis then opens for humidity and its six marks all land on the same side of zero, between 2.20 and 2.53 points high - the same direction for every city, which is a bias rather than noise and is the only finding in the project that was not put there by hand. A ranking check follows, joining the cities ordered by configured seasonal swing to the same cities ordered by recovered spread, and the order is preserved. The sequence closes by naming what the whole exercise rests on: 21,900 generated records at a fixed seed, so what it can establish is that the analysis reads its own input correctly, and nothing about any real city.
Read the full background

Problem

Why this work exists

An exploratory analysis of synthetic data is easy to present and hard to justify. Every chart looks like a finding and none of them is one, because the patterns were put there on purpose. The question worth answering is what such a project can be held to at all.

Contribution

What I can claim

Built the generator and the analysis, then used one against the other. Because the configured parameters are in source and the summary statistics are a tracked artefact, every recovered value has something to be wrong about - which turns a gallery of plots into a check that can fail.

Method

What an analysis of invented data can be held to

Everything in this dataset was put there on purpose, so every pattern in it is a pattern someone chose.

  1. Configure

    Each city is a handful of parameters: a base temperature, a seasonal swing, a precipitation scale, a humidity level.

  2. Generate

    Ten years of daily observations follow from those parameters at a fixed seed.

  3. Explore

    The exploratory pass does what such a pass does: distributions, seasonal comparisons, exceedance curves, correlations.

  4. Recover

    So each summary statistic is put beside the parameter that produced it.

  5. Catch

    Humidity does not come back.

  6. What this does not show

    None of this is weather. The dataset, the findings and the figures are produced by a seeded generator and are not station observations, climate evidence, forecasts, or a basis for any operational, scientific or policy decision. The humidity offset is a fact about the generator and of no consequence outside it; it is shown because it demonstrates that the check is capable of failing.

How it was built

System

Workflow and decisions

Two modules: a seeded generator with per-city temperature, amplitude, precipitation and humidity parameters, and one exploratory pass that writes 12 figures plus a per-city summary table. The summary is tracked, which is what makes the configuration-versus-recovery comparison possible from outside the repository.

  1. 1Generate 21,900 daily records for 6 cities at seed 42
  2. 2Reverse the seasons for the southern-hemisphere cities
  3. 3Summarise per city and track the result as an artefact
  4. 4distributions and a monthly temperature heatmap per city
  5. 5seasonal comparisons, with the southern hemisphere reversed
  6. 6precipitation exceedance curves
  7. 7a correlation matrix and pairwise scatter
  8. 8Compare every recovered statistic with the value it was configured with
  • Python
  • pandas
  • NumPy
  • matplotlib
  • seaborn

Evidence

What is actually versioned

Temperature, set against recoveredwithin 0.09 °C

Across all 6 cities the mean daily temperature in the tracked summary lands within 0.09 degrees of the base temperature the generator was configured with, scattered either side of it. The recovered spread also ranks the cities in exactly the configured order of seasonal amplitude. Both are statements about the generator, not about any city.

Humidity, set against recovered+2.20 to +2.53 points

Every one of the six cities recovers a mean humidity above its configured base, by a similar amount each time. One sign and one size across six independent cities is a property of how the generator builds humidity rather than sampling noise, and it is the only thing in this project that nobody put there deliberately.

What the data isgenerated, not observed

10 years of daily values from 2014-01-01 to 2023-12-29, produced at a fixed seed. The repository states that the dataset, findings and figures are not weather-station observations, climate evidence, forecasts, or a basis for operational, scientific or policy decisions.

How the work is checked

Quality controls

How the work is checked

  • The configured parameters live in source and the summary statistics are committed, so the comparison on this page is computed from both rather than asserted
  • Southern-hemisphere cities have their seasons reversed in the generator, so a seasonal plot is not quietly wrong for two of the six
  • The README puts the synthetic-data warning in its first lines, and repeats that city-level conclusions describe configured distributions rather than measured climates
  • The figures are regenerated from the tracked artefact rather than pasted, so a changed run changes what is shown

Limitations

Where the evidence stops

  • There is no weather here. A generator that is recovered accurately has demonstrated that the analysis is correct, not that anything is true
  • The humidity offset is a finding about the generator's own construction. It is interesting as a demonstration that the check works, and it is of no consequence to anyone
  • Six cities at one seed. Nothing here is repeated across seeds, so the comparison is a single observation rather than a distribution
  • The features are illustrative. They carry real units, which makes the plots readable and makes it correspondingly easy to misread them as measurements
What this changed in my practice

What this changed in my practice

A synthetic dataset is usually treated as a reason to lower the standard. It is the opposite: because the answer is in the repository, the analysis is one of the few that can actually be marked. Doing that turned up an offset in every city in the same direction, which no amount of looking at the twelve plots had shown me.

Next evidence milestone: Make the comparison part of the repository rather than part of this page. The configured values and the recovered ones are both already in the tree, so asserting the distance between them is a test - and the humidity offset is exactly the kind of thing that test should have failed on first.