Metadata-Version: 2.4
Name: ar6-sciplot
Version: 2.2.0
Summary: Evidence-backed plotting helpers and fidelity checks distilled from IPCC AR6 WGI visual practice
Author: GeoGeekLab
License-Expression: MIT
Project-URL: Homepage, https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill
Project-URL: Repository, https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill
Project-URL: Issues, https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill/issues
Project-URL: Releases, https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill/releases
Keywords: ar6,climate-science,data-visualization,ipcc,matplotlib,scientific-plotting,scientific-visualization
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: THIRD_PARTY_NOTICES.md
Requires-Dist: numpy>=1.26
Requires-Dist: pandas>=2.1
Requires-Dist: matplotlib>=3.8
Requires-Dist: xarray>=2024.6
Requires-Dist: scipy>=1.11
Requires-Dist: PyYAML>=6.0
Provides-Extra: climate
Requires-Dist: dask[array]>=2024.6; extra == "climate"
Requires-Dist: cartopy>=0.23; extra == "climate"
Requires-Dist: regionmask>=0.12; extra == "climate"
Requires-Dist: cf-xarray>=0.9; extra == "climate"
Requires-Dist: pint-xarray>=0.4; extra == "climate"
Requires-Dist: flox>=0.9; extra == "climate"
Requires-Dist: xclim>=0.50; extra == "climate"
Requires-Dist: xesmf>=0.8; extra == "climate"
Requires-Dist: zarr>=2.18; extra == "climate"
Requires-Dist: pyam-iamc>=2.2; extra == "climate"
Provides-Extra: qa
Requires-Dist: pytest>=8; extra == "qa"
Requires-Dist: pytest-cov>=5; extra == "qa"
Requires-Dist: pytest-mpl>=0.17; extra == "qa"
Requires-Dist: ruff>=0.6; extra == "qa"
Requires-Dist: mypy>=1.11; extra == "qa"
Requires-Dist: pre-commit>=3.8; extra == "qa"
Requires-Dist: build>=1.2; extra == "qa"
Requires-Dist: twine>=6; extra == "qa"
Provides-Extra: workflow
Requires-Dist: snakemake>=8; extra == "workflow"
Requires-Dist: conda-lock>=2.5; extra == "workflow"
Dynamic: license-file

<div align="center">

# ipcc-wg1-scientific-plotting-skill

**Evidence-backed visual grammar and fidelity checks for IPCC AR6 WGI scientific figures.**

<code>source → profile → render → audit → reproduce</code>

[![CI](https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill/actions/workflows/ci.yml/badge.svg)](https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill/actions/workflows/ci.yml)
[![Reference reproductions](https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill/actions/workflows/reference-reproductions.yml/badge.svg)](https://github.com/GeoGeekLab/ipcc-wg1-scientific-plotting-skill/actions/workflows/reference-reproductions.yml)
[![Python](https://img.shields.io/badge/Python-3.11%20%7C%203.12-3776AB?style=flat-square&logo=python&logoColor=white)](pyproject.toml)
[![AR6 WGI](https://img.shields.io/badge/IPCC-AR6%20WGI-111111?style=flat-square)](references/SOURCES.md)
[![Fidelity](https://img.shields.io/badge/fidelity-strict%20%7C%20adapted-2ea44f?style=flat-square)](references/fidelity_checklist.md)

**Not a Matplotlib theme.** The project encodes AR6/WGI visual semantics, delivery geometry,
official colour assets, uncertainty grammar, provenance, and machine-checkable fidelity.

</div>

> [!IMPORTANT]
> Independent project. Not an official IPCC product and does not imply IPCC endorsement.

## From styling to fidelity

<img src="examples/visual_comparison/default-to-fidelity.svg" alt="Four-panel comparison from Matplotlib defaults and IPCC-ish styling to adapted and strict-contract AR6 visual grammar">

The same **synthetic** SSP trajectories are shown four ways: Matplotlib defaults,
appearance-only “IPCC-ish” styling, an explicit adapted profile, and the stricter
`ar6-report` contract. The point is not that the fourth mini-panel is itself an
official IPCC figure; it is that a fidelity claim needs **semantic tokens, an
explicit profile, audit gates, and disclosed requirements** rather than visual
resemblance alone.

The comparison is reproducible with
[`examples/visual_comparison.py`](examples/visual_comparison.py); PNG and SVG
outputs plus the interpretation boundary live in
[`examples/visual_comparison/`](examples/visual_comparison/).

## See the reference reproductions first

These figures are regenerated from **pinned official IPCC AR6 WGI source repositories**,
not synthetic demo data. Source commits, physical dimensions, and SHA256 checksums are
recorded in the [reference gallery](examples/ipcc_reference/README.md) and
[manifest](examples/ipcc_reference/outputs/manifest.json).

<table>
<tr>
<td width="50%" valign="top">
<strong>Chapter 3 — Figure 3.2b</strong><br>
Scatter + fitted relationship.<br><br>
<img src="examples/ipcc_reference/outputs/ch03_fig3_2b_scatter.png" alt="Chapter 3 Figure 3.2b reproduction">
</td>
<td width="50%" valign="top">
<strong>Chapter 10 — Figure 10.20b</strong><br>
Mediterranean station map.<br><br>
<img src="examples/ipcc_reference/outputs/ch10_fig10_20b_stations.png" alt="Chapter 10 Figure 10.20b reproduction">
</td>
</tr>
<tr>
<td width="50%" valign="top">
<strong>Chapter 2 — Figure 2.3</strong><br>
Paleo CO₂ proxies + uncertainty.<br><br>
<img src="examples/ipcc_reference/outputs/ch02_fig2_3_co2_proxy.png" alt="Chapter 2 Figure 2.3 reproduction">
</td>
<td width="50%" valign="top">
<strong>Chapter 6 — Figure 6.18 source</strong><br>
Historical + scenario CH₄ emissions.<br><br>
<img src="examples/ipcc_reference/outputs/ch06_fig6_18_ch4_emissions.png" alt="Chapter 6 Figure 6.18 source reproduction">
</td>
</tr>
</table>

## Why this is different

A lot of “IPCC-style” plotting stops at a diverging palette, a sans-serif font,
and some hatching. This repository treats AR6 WGI as a **visual system with evidence
and failure conditions**, not a theme.

- **Evidence-backed rules** — WGI guides, TSU review comments, official colormaps,
  chapter code, Atlas guidance, and published reference figures are kept distinct.
- **Semantic colour** — SSP/RCP colours and variable-specific map palettes carry
  meaning; they are not a decorative colour cycle.
- **Explicit fidelity modes** — strict/IPCC-faithful and adapted/IPCC-inspired are
  separate claims.
- **Fail-closed strict mode** — no silent fallback to <code>viridis</code>, <code>RdBu</code>,
  cmocean, or an arbitrary font while still claiming fidelity.
- **Method ≠ style** — median, 17–83%, 80% agreement, FDR, weighting, and projection
  remain analysis/reference choices unless evidence says otherwise.
- **Auditable outputs** — physical dimensions, typography, semantic colours,
  official-colormap use, provenance, and reference regressions can be checked.

The goal is not to make a plot look vaguely IPCC-ish. The goal is to make the
**fidelity claim inspectable**.

## Audit the fidelity claim

The audit layer is designed for both humans and CI. Existing code can keep using
`audit_figure(fig)`; new integrations can use the structured
`audit_figure_report(fig)` API or the `ar6plot` CLI.

A figure script exposes a zero-argument factory returning a Matplotlib
`Figure`:

~~~python
def make_figure():
    ...
    return fig
~~~

Run the machine-checkable contract:

~~~bash
ar6plot audit examples/audit_demo.py --strict-dimensions
~~~

Example report:

~~~text
AR6 fidelity audit — PASS
Profile: ar6-report

PASS  text.unit-convention         axis and annotation unit syntax passed
SKIP  typography.arial             strict font check not requested
PASS  delivery.width               figure width matches an IPCC delivery width
PASS  delivery.height              figure height is within the delivery maximum
PASS  scenario.color.0.0           scenario 'SSP1-2.6' uses the ar6-report semantic colour
PASS  scenario.color.0.1           scenario 'SSP2-4.5' uses the ar6-report semantic colour
PASS  scenario.color.0.2           scenario 'SSP5-8.5' uses the ar6-report semantic colour
SKIP  map.official-colormap        official map-colormap check not requested
SKIP  reference.manual-review      projection, panel geometry, annotation, and scientific method require reference-specific review

Summary: 6 passed, 0 failed, 3 skipped
~~~

For CI and other tooling:

~~~bash
ar6plot audit examples/audit_demo.py \
  --strict-dimensions \
  --format json \
  --output outputs/audit.json
~~~

Exit codes are deliberate: **0** = all requested machine checks pass, **1** = one
or more checks fail, **2** = the audit could not run. Exact reproduction still
requires the explicitly reported manual/reference-specific checks.

## Quick start

Requires Python 3.11+.

~~~bash
python -m pip install ar6-sciplot
~~~

The PyPI distribution is named `ar6-sciplot`; the Python import remains
`ipcc_sciplot`.

Run a minimal, copy-pasteable example:

~~~python
import matplotlib.pyplot as plt
import numpy as np

from ipcc_sciplot import audit_figure, axis_label, publication_context, scenario_style

year = np.arange(2015, 2101)
warming = np.linspace(1.1, 2.7, year.size)
style = scenario_style("SSP2-4.5", profile="ar6-report")

with publication_context(width="double", strict_font=False):
    fig, ax = plt.subplots()
    ax.plot(year, warming, color=style.color, label="SSP2-4.5")
    ax.set_xlabel("Year")
    ax.set_ylabel(axis_label("Temperature change", "°C"))
    ax.legend()

issues = audit_figure(
    fig,
    profile="ar6-report",
    strict_font=False,
    strict_dimensions=True,
)

print("fidelity audit:", issues or "passed")
plt.show()
~~~

This first run deliberately allows a font substitution. A figure should only be
called **strictly IPCC-faithful** when all strict requirements are satisfied,
including Arial where required.

For map/climate workflows:

~~~bash
python -m pip install "ar6-sciplot[climate]"
git clone https://github.com/IPCC-WG1/colormaps.git
export IPCC_WG1_COLORMAPS_DIR=/path/to/colormaps
~~~

Strict maps load the official WGI colormap assets directly and intentionally have
**no generic palette fallback**.

## Choose the fidelity contract

| Goal | Profile / mode | Contract |
| --- | --- | --- |
| Reproduce a published AR6 figure | <code>ar6-report</code> + strict | Match the published figure first, then contemporaneous AR6 guidance and source code. |
| Create a new figure using the updated WGI guidance | <code>wgi-guide-2022</code> + strict | Use the June-2022 guide explicitly rather than silently rewriting final-report semantics. |
| Use the visual language with documented substitutions | adapted / IPCC-inspired | Substitutions are allowed, but the result must not be labelled exact or faithful. |

Two style profiles are explicit and are never silently mixed:

~~~text
ar6-report       → final-report-era AR6 semantics
wgi-guide-2022   → June-2022 WGI guide update
~~~

## Execution model

~~~text
SOURCE → PROFILE → FIGURE CONTRACT → RENDER → AUDIT → REFERENCE
~~~

| Stage | Question |
| --- | --- |
| **Source** | Which WGI evidence or published figure defines the rule? |
| **Profile** | Are we reproducing final-report AR6 or using the 2022 guide? |
| **Figure contract** | What quantity, geometry, uncertainty method, palette, projection, and output size are required? |
| **Render** | Which archetype and semantic tokens apply? |
| **Audit** | What can be machine-checked, and what still needs visual comparison? |
| **Reference** | Can the output be regenerated from pinned source data and verified by SHA256? |

## What is encoded

~~~text
delivery
  ├── 90 / 180 mm print widths
  ├── ≤ 250 mm height
  ├── 9 / 11 pt WGI typography
  ├── 0.5 pt axis grammar
  └── 350 ppi raster master

semantics
  ├── SSP / RCP colours
  ├── WGI generic line colours
  ├── variable-specific official colormaps
  └── report-era vs 2022 profiles

uncertainty
  ├── model agreement
  ├── insufficient data
  └── statistical significance

qa
  ├── text + unit conventions
  ├── semantic colour audit
  ├── physical-size audit
  ├── official-colormap audit
  └── source-data regression gallery
~~~

## Repository map

```text
ipcc-wg1-scientific-plotting-skill/
├── SKILL.md                         # skill contract + routing
├── scripts/ipcc_sciplot/
│   ├── tokens.py                    # semantic WGI colours + design tokens
│   ├── colormaps.py                 # official WGI asset loader
│   ├── style.py                     # delivery geometry + typography
│   ├── archetypes.py                # recurring figure families
│   ├── maps.py                      # map context + uncertainty layers
│   ├── fidelity.py                  # machine-checkable fidelity audit
│   ├── uncertainty.py               # statistical helpers, not style defaults
│   └── provenance.py                # reproducibility metadata
├── references/
│   ├── SOURCES.md                   # source hierarchy
│   ├── evidence_matrix.md           # rule → evidence → scope → confidence
│   ├── ipcc_visual_grammar.md        # canonical visual grammar
│   ├── figure_archetypes.md          # figure-family rules
│   ├── fidelity_checklist.md         # strict gate
│   └── statistical_rules.md          # method/style separation
├── examples/
│   ├── quickstart.py
│   └── ipcc_reference/              # pinned source-data regressions
├── templates/
│   └── figure_recipe.yaml
└── tests/
```

## Verification

Run the local contract:

```bash
ruff check .
pytest -q
python examples/quickstart.py
python scripts/check_figure.py   outputs/quickstart.pdf   --metadata outputs/quickstart.provenance.json
```

Rebuild the pinned IPCC reference gallery:

```bash
python -m pip install cartopy
python examples/ipcc_reference/generate_all.py
git diff --exit-code -- examples/ipcc_reference/outputs
```

CI covers Python 3.11 and 3.12. The reference workflow regenerates the four official-source cases and fails if the committed gallery drifts.

## Evidence model

The source hierarchy is deliberately explicit:

```text
published reference figure
        ↓
WGI visual guidance + TSU review evidence
        ↓
official IPCC-WG1 colour assets
        ↓
chapter / final-figure implementation code
        ↓
Atlas uncertainty guidance
        ↓
general scientific-visualisation practice
```

Start with:

- [source corpus](references/SOURCES.md)
- [evidence matrix](references/evidence_matrix.md)
- [visual grammar](references/ipcc_visual_grammar.md)
- [figure archetypes](references/figure_archetypes.md)
- [fidelity checklist](references/fidelity_checklist.md)

## The boundary

This repository does **not** claim that one Matplotlib theme can represent all of AR6 WGI.

It also does not turn scientific-method choices into fake visual defaults.

```text
17–83% range       ≠ IPCC style
80% agreement      ≠ IPCC style
median             ≠ IPCC style
equal-model weight ≠ IPCC style
Robinson           ≠ universal IPCC projection
```

Those choices belong to the analysis or the published reference figure.

## License and third-party material

Original project code and documentation are licensed under the [MIT License](LICENSE).

That license does **not** relicense IPCC figures, source data, colour assets,
chapter code, fonts, or other third-party material referenced or fetched by the
reproducibility workflows. See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)
and [the source corpus](references/SOURCES.md) before redistributing upstream
material.

This is an independent project. It is not an official IPCC product and does not
imply IPCC endorsement.

---

<div align="center">

**Source it. Encode it. Render it. Prove it.**

</div>
