Skip to content

Commit cfa4a6b

Browse files
Optimize caption produced by ecs.py (#4040)
Co-authored-by: Bettina Gier <[email protected]>
1 parent b4c2501 commit cfa4a6b

File tree

2 files changed

+57
-22
lines changed

2 files changed

+57
-22
lines changed

esmvaltool/diag_scripts/climate_metrics/ecs.py

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
relative to this diagnostic script or as absolute path.
3333
savefig_kwargs : dict, optional
3434
Keyword arguments for :func:`matplotlib.pyplot.savefig`.
35-
seaborn_settings : dict, optional
36-
Options for :func:`seaborn.set_theme` (affects all plots).
35+
seaborn_settings: dict, optional
36+
Options for :func:`seaborn.set_theme` (affects all plots). By default, uses
37+
``style: ticks``.
3738
sep_year : int, optional (default: 20)
3839
Year to separate regressions of complex Gregory plot. Only effective if
3940
``complex_gregory_plot`` is ``True``.
@@ -243,7 +244,10 @@ def _plot_complex_gregroy_plot(cfg, axes, tas_cube, rtnt_cube, reg_all):
243244
marker="o",
244245
s=8,
245246
alpha=0.7,
246-
label=f"first {sep:d} years: ECS = {ecs_first:.2f} K",
247+
label=(
248+
f"first {sep:d} years: ECS = {ecs_first:.2f} K "
249+
f"($R^2$ = {reg_first.rvalue**2:.2f})"
250+
),
247251
)
248252
axes.scatter(
249253
tas_cube.data[sep:],
@@ -252,8 +256,10 @@ def _plot_complex_gregroy_plot(cfg, axes, tas_cube, rtnt_cube, reg_all):
252256
marker="o",
253257
s=8,
254258
alpha=0.7,
255-
label=f"last {tas_cube.shape[0] - sep:d} years: ECS = "
256-
f"{ecs_last:.2f} K",
259+
label=(
260+
f"last {tas_cube.shape[0] - sep:d} years: ECS = {ecs_last:.2f} K "
261+
f"($R^2$ = {reg_last.rvalue**2:.2f})"
262+
),
257263
)
258264
axes.plot(x_reg, y_reg_first, color=COLORS[0], linestyle="-", alpha=0.6)
259265
axes.plot(x_reg, y_reg_last, color=COLORS[1], linestyle="-", alpha=0.6)
@@ -399,11 +405,16 @@ def read_external_file(cfg):
399405
return (ecs, feedback_parameter, filepath)
400406

401407

402-
def plot_gregory_plot(cfg, dataset_name, tas_cube, rtnt_cube, reg_stats):
408+
def plot_gregory_plot(cfg, dataset_name, tas_data, rtnt_data, reg_stats):
403409
"""Plot linear regression used to calculate ECS."""
410+
tas_cube = tas_data["cube"]
411+
rtnt_cube = rtnt_data["cube"]
412+
dataset_id = dataset_name
413+
if "ensemble" in tas_data:
414+
dataset_id += f" (ensemble member {tas_data['ensemble']})"
415+
404416
(_, axes) = plt.subplots()
405417
ecs = -reg_stats.intercept / (2 * reg_stats.slope)
406-
project = tas_cube.attributes["project"]
407418

408419
# Regression line
409420
x_reg = np.linspace(cfg["x_lim"][0] - 1.0, cfg["x_lim"][1] + 1.0, 2)
@@ -414,6 +425,23 @@ def plot_gregory_plot(cfg, dataset_name, tas_cube, rtnt_cube, reg_stats):
414425
legend = _plot_complex_gregroy_plot(
415426
cfg, axes, tas_cube, rtnt_cube, reg_stats
416427
)
428+
sep = cfg["sep_year"]
429+
caption = (
430+
f"Global annual mean top of the atmosphere (TOA) net radiation "
431+
f"flux anomaly N vs. global annual mean near-surface air "
432+
f"temperature anomaly ΔT for the first {sep:d} years (blue "
433+
f"circles) and last {tas_cube.shape[0] - sep:d} years (orange "
434+
f"circles) of the abrupt 4x CO2 experiment for model "
435+
f"{dataset_id}. Anomalies are calculated relative to a "
436+
f"pre-industrial control simulation of the same model. The solid "
437+
f"lines correspond to ordinary linear regressions between N "
438+
f"and ΔT for the different years (the black lines corresponds to "
439+
f"all years). In the legend, R2 corresponds to the coefficient "
440+
f"of determination of the linear regressions. The equilibrium "
441+
f"climate sensitivity (ECS) is estimated as the x-intercept of "
442+
f"the linear regressions (interception of the solid and dashed "
443+
f"lines) divided by 2."
444+
)
417445
else:
418446
axes.scatter(
419447
tas_cube.data,
@@ -431,10 +459,23 @@ def plot_gregory_plot(cfg, dataset_name, tas_cube, rtnt_cube, reg_stats):
431459
rf"R$^2$ = {reg_stats.rvalue**2:.2f}, ECS = {ecs:.2f} K",
432460
transform=axes.transAxes,
433461
)
462+
caption = (
463+
f"Global annual mean top of the atmosphere (TOA) net radiation "
464+
f"flux anomaly N vs. global annual mean near-surface air "
465+
f"temperature anomaly ΔT for {tas_cube.shape[0]} years (blue "
466+
f"circles) of the abrupt 4x CO2 experiment for model {dataset_id}. "
467+
f"Anomalies are calculated relative to a pre-industrial control "
468+
f"simulation of the same model. The solid black line corresponds "
469+
f"to an ordinary linear regression between N and ΔT. On the top "
470+
f"left, R2 corresponds to the coefficient of determination of "
471+
f"the linear regression. The equilibrium climate sensitivity "
472+
f"(ECS) is estimated as the x-intercept of the linear regression "
473+
f"(interception of the solid and dashed black lines) divided by 2."
474+
)
434475
axes.axhline(0.0, color="gray", linestyle=":")
435476

436477
# Plot appearance
437-
axes.set_title(f"Gregory regression for {dataset_name} ({project})")
478+
axes.set_title(f"Gregory regression for {dataset_id}", pad=15.0)
438479
axes.set_xlabel("ΔT [K]")
439480
axes.set_ylabel(r"N [W m$^{-2}$]")
440481
axes.set_xlim(cfg["x_lim"])
@@ -455,17 +496,8 @@ def plot_gregory_plot(cfg, dataset_name, tas_cube, rtnt_cube, reg_stats):
455496
)
456497

457498
# Provenance
458-
provenance_record = get_provenance_record(
459-
f"Scatterplot between TOA radiance and global mean surface "
460-
f"temperature anomaly for 150 years of the abrupt 4x CO2 experiment "
461-
f"including linear regression to calculate ECS for {dataset_name} "
462-
f"({project})."
463-
)
464-
provenance_record.update(
465-
{
466-
"plot_types": ["scatter"],
467-
}
468-
)
499+
provenance_record = get_provenance_record(caption)
500+
provenance_record["plot_types"] = ["scatter"]
469501

470502
return (netcdf_path, plot_path, provenance_record)
471503

@@ -540,7 +572,7 @@ def write_data(cfg, ecs_data, feedback_parameter_data, ancestor_files):
540572
def main(cfg):
541573
"""Run the diagnostic."""
542574
cfg = set_default_cfg(cfg)
543-
sns.set_theme(**cfg.get("seaborn_settings", {}))
575+
sns.set_theme(**cfg.get("seaborn_settings", {"style": "ticks"}))
544576

545577
# Read external file if desired
546578
if cfg.get("read_external_file"):
@@ -574,7 +606,11 @@ def main(cfg):
574606

575607
# Plot Gregory plots
576608
(path, plot_path, provenance_record) = plot_gregory_plot(
577-
cfg, dataset_name, tas_cube, rtnt_cube, reg
609+
cfg,
610+
dataset_name,
611+
tas_data[dataset_name][0],
612+
rtnt_data[dataset_name][0],
613+
reg,
578614
)
579615

580616
# Provenance

esmvaltool/references/gregory04grl.bibtex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
@article{gregory04grl,
22
doi = {10.1029/2003gl018747},
3-
url = {https://doi.org/10.1029%2F2003gl018747},
43
year = 2004,
54
publisher = {American Geophysical Union ({AGU})},
65
volume = {31},

0 commit comments

Comments
 (0)