taylor_diagram

taylor_diagram

Module: taylor_diagram.py

This module generates Taylor diagrams [Taylor, 2001] for evaluating bias-corrected precipitation products against independent BMKG weather station observations across Indonesia.

Taylor diagrams simultaneously display three complementary statistics on a single polar plot: Pearson correlation (angular position), normalized standard deviation (radial distance), and centered RMSE (arc contours). A product that perfectly reproduces observed variability coincides with the reference point at correlation = 1.0 and normalized std = 1.0.

The module supports four spatial aggregation levels: 1. Domain-wide – all stations pooled into a single diagram. 2. By island group – seven main Indonesian island regions. 3. By province – one diagram per province (minimum station threshold). 4. By station – individual station markers with aggregate overlay.

Products compared: CPC-UNI, IMERG-L, IMERG-F, LS, LSEQM, LSEQM+DL. Reference: BMKG weather station daily observations (180 stations).

The compute_all_taylor_stats function loops over all 36 dekadal periods, extracts gridded values at station locations, and accumulates running statistics via the Accumulator class. This avoids loading all data into memory simultaneously. The generate* functions then produce the polar plots from the accumulated statistics.

Author: Benny Istanto Applied Climatology Study Program, Department of Geophysics and Meteorology, Bogor Agricultural University, Indonesia Email: bennyistanto@apps.ipb.ac.id

with supervision from Prof. Rizaldi Boer and Dr. I Putu Santikayasa

Update: 2026.03

Functions

Name Description
compute_all_taylor_stats Compute Taylor statistics for all products at all stations.
generate_all_taylor_diagrams Generate all Taylor diagram variants and save to disk.
generate_domain_taylor Generate and save a domain-wide Taylor diagram.
generate_island_taylor Generate per-island Taylor diagrams in a multi-panel figure.
generate_per_dekad_taylor_diagrams Generate Taylor diagrams evaluated at per-dekad resolution.
generate_province_taylor Generate per-province Taylor diagrams.
generate_station_taylor Generate station-level Taylor diagram.
plot_taylor_diagram Plot a Taylor diagram using PRODUCT_STYLES markers.
print_taylor_stats Print Taylor statistics as a formatted table.
save_dekad_taylor_stats_csv Save per-station per-dekad Taylor statistics to CSV.
save_taylor_stats_csv Save per-station Taylor statistics to CSV.

compute_all_taylor_stats

taylor_diagram.compute_all_taylor_stats(config=None, progress=True)

Compute Taylor statistics for all products at all stations.

Loops over all 36 dekads, extracts gridded values at BMKG station locations, and accumulates running sums for on-the-fly computation of correlation, standard deviation, and RMSE.

Parameters

Name Type Description Default
config module Configuration module (src.config). If None, imports it. None
progress bool Print progress messages to stdout. True

Returns

Name Type Description
acc _Accumulator Per-station running sums for all products (pooled across dekads).
station_locs DataFrame Station metadata (ID_WMO, Lon, Lat, Province, Region).
acc_by_dekad dict Mapping {(month, dekad_start): _Accumulator} with separate running sums for each of the 36 dekadal periods.

generate_all_taylor_diagrams

taylor_diagram.generate_all_taylor_diagrams(config=None, output_dir=None)

Generate all Taylor diagram variants and save to disk.

Generates both pooled-across-dekads and per-dekad diagrams.

Parameters

Name Type Description Default
config module Configuration module. If None, imports src.config. None
output_dir str Output directory. Defaults to {output_dir}/figures/taylor. None

Returns

Name Type Description
acc _Accumulator
station_locs DataFrame
acc_by_dekad dict

generate_domain_taylor

taylor_diagram.generate_domain_taylor(
    acc,
    station_locs,
    output_dir=None,
    diagram_label=None,
    **plot_kwargs,
)

Generate and save a domain-wide Taylor diagram.

Parameters

Name Type Description Default
acc _Accumulator or _DekadAggregator required
station_locs DataFrame required
output_dir str None
diagram_label str Label suffix for title and filename (e.g. 'per_dekad'). None
**plot_kwargs Forwarded to :func:plot_taylor_diagram. {}

Returns

Name Type Description
fig Figure

generate_island_taylor

taylor_diagram.generate_island_taylor(
    acc,
    station_locs,
    output_dir=None,
    diagram_label=None,
    **plot_kwargs,
)

Generate per-island Taylor diagrams in a multi-panel figure.

Parameters

Name Type Description Default
acc _Accumulator or _DekadAggregator required
station_locs DataFrame required
output_dir str None
diagram_label str Label suffix for title and filename (e.g. 'per_dekad'). None
**plot_kwargs Forwarded to :func:plot_taylor_diagram (except figsize). {}

Returns

Name Type Description
fig Figure or None

generate_per_dekad_taylor_diagrams

taylor_diagram.generate_per_dekad_taylor_diagrams(
    acc_by_dekad,
    station_locs,
    output_dir=None,
    individual=True,
    summary=True,
)

Generate Taylor diagrams evaluated at per-dekad resolution.

Two modes:

  • Summary (summary=True): one diagram per spatial level showing the median across all 36 dekads. Uses :class:_DekadAggregator.

  • Individual (individual=True): one diagram per dekad per spatial level, with _month{MM}_dekad{DD} in the filename.

Parameters

Name Type Description Default
acc_by_dekad dict Mapping {(month, dekad_start): _Accumulator}. required
station_locs DataFrame required
output_dir str None
individual bool Generate one diagram per dekad (36 × spatial-levels). True
summary bool Generate summary diagrams (median across dekads). True

generate_province_taylor

taylor_diagram.generate_province_taylor(
    acc,
    station_locs,
    output_dir=None,
    min_stations=3,
    diagram_label=None,
    **plot_kwargs,
)

Generate per-province Taylor diagrams.

Provinces with fewer than min_stations are skipped.

Parameters

Name Type Description Default
acc _Accumulator or _DekadAggregator required
station_locs DataFrame required
output_dir str None
min_stations int Minimum stations per province. 3
diagram_label str Label suffix for title and filename (e.g. 'per_dekad'). None
**plot_kwargs Forwarded to :func:plot_taylor_diagram. {}

Returns

Name Type Description
fig Figure or None

generate_station_taylor

taylor_diagram.generate_station_taylor(
    acc,
    station_locs,
    output_dir=None,
    products_to_show=None,
    normalize=True,
    max_std_ratio=2.0,
    diagram_label=None,
)

Generate station-level Taylor diagram.

Individual station markers are shown as small semi-transparent points for each product, with median-of-per-station aggregates overlaid as larger opaque markers. Each station is normalised by its own observation standard deviation so that stations with different climatologies contribute comparably.

Parameters

Name Type Description Default
acc _Accumulator or _DekadAggregator required
station_locs DataFrame required
output_dir str None
products_to_show list of str None
normalize bool True
max_std_ratio float 2.0
diagram_label str Label suffix for title and filename (e.g. 'per_dekad'). None

Returns

Name Type Description
fig Figure

Notes

Direct pooling (acc.compute()) mixes spatial and temporal variance: stations with different climates inflate the pooled variance and dilute the temporal correlation (Simpson’s paradox). Individual stations may show corr 0.6–0.95, while the pooled correlation drops to ~0.3. Using the median of per-station normalised statistics gives a representative typical station aggregate that is visually consistent with the scatter cloud.

plot_taylor_diagram

taylor_diagram.plot_taylor_diagram(
    stats,
    title=None,
    normalize=True,
    figsize=(8, 8),
    ax=None,
    max_std_ratio=2.0,
    products_to_show=None,
    legend=True,
    **_ignored,
)

Plot a Taylor diagram using PRODUCT_STYLES markers.

Uses a custom polar grid (no external dependency). Markers match :data:PRODUCT_STYLES exactly, so shared legends built with :func:_product_legend_handles are always consistent.

Parameters

Name Type Description Default
stats list of dict Each dict must have key, correlation, std_obs, std_prd. required
title str None
normalize bool Divide all standard deviations by the reference std. True
figsize tuple Only used when ax is None. (8, 8)
ax matplotlib.axes.Axes Existing regular (non-polar) axes for subplot usage. A polar axes is created at the same position automatically. None
max_std_ratio float Upper limit for the radial axis. 2.0
products_to_show list of str Restrict to these product keys. None
legend bool Add a legend (standalone mode only). True

Returns

Name Type Description
(fig, ax)

print_taylor_stats

taylor_diagram.print_taylor_stats(stats, title=None)

Print Taylor statistics as a formatted table.

Parameters

Name Type Description Default
stats list of dict Output of _Accumulator.compute(). required
title str None

save_dekad_taylor_stats_csv

taylor_diagram.save_dekad_taylor_stats_csv(
    acc_by_dekad,
    station_locs,
    output_file,
)

Save per-station per-dekad Taylor statistics to CSV.

Parameters

Name Type Description Default
acc_by_dekad dict Mapping {(month, dekad_start): _Accumulator}. required
station_locs DataFrame required
output_file str required

Returns

Name Type Description
DataFrame

save_taylor_stats_csv

taylor_diagram.save_taylor_stats_csv(acc, station_locs, output_file)

Save per-station Taylor statistics to CSV.

Parameters

Name Type Description Default
acc _Accumulator required
station_locs DataFrame required
output_file str required
Back to top