From d16ab442779b4f9349d81fea014947bba4f7cf3a Mon Sep 17 00:00:00 2001 From: Davide Madrisan Date: Sat, 15 Nov 2025 15:03:08 +0100 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20new=20plot=20with=20temps=20closing?= =?UTF-8?q?=20in=20to=201.5=C2=B0C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Davide Madrisan --- README.md | 30 ++++ hadcrut5_close.py | 133 ++++++++++++++++++ plots.sh | 6 + plots/HadCRUT5-global-threshold-1880-1920.png | 3 + 4 files changed, 172 insertions(+) create mode 100755 hadcrut5_close.py create mode 100644 plots/HadCRUT5-global-threshold-1880-1920.png diff --git a/README.md b/README.md index a308416..3b4786b 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,36 @@ $ ./hadcrut5_stripe.py --region global ``` ![HadCRUT5 global warming stripe](plots/HadCRUT5-global-stripe.png) +## hadcrut5_close.py — Script usage + +``` +usage: hadcrut5_close.py [-h] [-f OUTFILE] [-p PERIOD] [-r {global,northern,southern}] [-v] + +Parse and plot the approach of HadCRUT5 dataset to a threshold temperature v2025.1 (stable) +Copyright (C) 2020-2025 Davide Madrisan +License: GNU General Public License v3.0 + +options: + -h, --help show this help message and exit + -f, --outfile OUTFILE + name of the output PNG file + -p, --period PERIOD show anomalies related to 1961-1990 (default), 1850-1900, or 1880-1920 + -r, --region {global,northern,southern} + select between Global (default), Northern, or Southern Temperatures + -v, --verbose make the operation more talkative + +examples: + hadcrut5_close.py + hadcrut5_close.py --period "1850-1900" --region global + hadcrut5_close.py --period "1880-1920" --outfile "HadCRUT5-1880-1920-threshold.png" +``` + +Below is a generated plot image for global anomalies related to the period `1880-1920` with a threshold set to 1.5°C. +``` +$ ./hadcrut5_close.py --period "1880-1920" --region global +``` +![HadCRUT5 global warming close](plots/HadCRUT5-global-threshold-1880-1920.png) + # License The Python code of this project is released under the [GPL-3.0 license](https://github.com/madrisan/HadCRUT5/blob/main/LICENSE). diff --git a/hadcrut5_close.py b/hadcrut5_close.py new file mode 100755 index 0000000..f52942e --- /dev/null +++ b/hadcrut5_close.py @@ -0,0 +1,133 @@ +#!/usr/bin/python3 +# Copyright (c) 2025 Davide Madrisan +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Plotting the approach of HadCRUT5 dataset to a threshold temperature. +""" + +import argparse + +import matplotlib.pyplot as plt +from matplotlib.ticker import MultipleLocator +import numpy as np + +from hadcrut5lib import argparser, HadCRUT5 + + +def parse_args() -> argparse.Namespace: + """This function parses and return arguments passed in""" + descr = "Parse and plot the approach of HadCRUT5 dataset to a threshold temperature" + examples = [ + "%(prog)s", + '%(prog)s --period "1850-1900" --region global', + '%(prog)s --period "1880-1920" --outfile "HadCRUT5-1880-1920-threshold.png"', + ] + + parser = argparser(descr, examples) + parser.add_argument( + "-f", + "--outfile", + action="store", + dest="outfile", + help="name of the output PNG file", + ) + parser.add_argument( + "-p", + "--period", + action="store", + dest="period", + default="1961-1990", + help="show anomalies related to 1961-1990 (default), 1850-1900, or 1880-1920", + ) + parser.add_argument( + "-r", + "--region", + choices=["global", "northern", "southern"], + action="store", + dest="region", + default="global", + help="select between Global (default), Northern, or Southern Temperatures", + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + dest="verbose", + help="make the operation more talkative", + ) + + return parser.parse_args() + + +def plotline(hc5: HadCRUT5, region: str, outfile: str, threshold): + """ + Create a plot for the specified period and arguments and diplay it or save + it to file if outfile is set + """ + hc5.datasets_download() + hc5.datasets_load() + hc5.datasets_normalize() + + years = hc5.dataset_years() + ylabel = f"Temperature Anomalies relative to {hc5.dataset_period}" + + regions_switch = { + "global": hc5.GLOBAL_REGION, + "northern": hc5.NORTHERN_REGION, + "southern": hc5.SOUTHERN_REGION, + } + _, mean, _ = hc5.dataset_normalized_data(regions_switch[region]) + + _, ax = plt.subplots() + ax.set_frame_on(False) + ax.tick_params(axis="both", which="both", length=0) + ax.yaxis.set_major_formatter("{x:.1f}°C") + ax.yaxis.set_major_locator(MultipleLocator(0.5)) + + plt.hlines( + threshold, + np.min(years), + np.max(years), + colors="white", + linestyles="dotted", + ) + + ymin = min(mean) + ymax = max(mean) + plt.imshow( + np.linspace(0, 1, 256).reshape(-1, 1), + origin="lower", + aspect="auto", + cmap="coolwarm", + extent=[years[0], years[-1], ymin, 2.0], + ) + plt.fill_between(years, ymin, mean, color="w") + + plt.title(f"HadCRUT5: Closing in to {threshold}°C") + plt.xlabel("year", fontsize=10) + plt.ylabel(ylabel, fontsize=10) + + plt.plot(years, mean, "steelblue", linewidth=2) + + if outfile: + plt.savefig(outfile, transparent=False) + else: + plt.show() + + +# pylint: disable=C0116 +def main(): + args = parse_args() + + regions = (args.region == "global", args.region == "northern", args.region == "southern") + hc5 = HadCRUT5( + period=args.period, + regions=regions, + verbose=args.verbose, + ) + + plotline(hc5, region=args.region, outfile=args.outfile, threshold=1.5) + + +main() diff --git a/plots.sh b/plots.sh index 243dc01..00b6bd8 100755 --- a/plots.sh +++ b/plots.sh @@ -30,4 +30,10 @@ echo "creating stripe image ..." --region global \ --outfile plots/HadCRUT5-global-stripe.png +echo "creating plot closing in to 1.5°C ..." +./hadcrut5_close.py \ + --period "1880-1920" \ + --region global \ + --outfile plots/HadCRUT5-global-threshold-1880-1920.png + echo "done." diff --git a/plots/HadCRUT5-global-threshold-1880-1920.png b/plots/HadCRUT5-global-threshold-1880-1920.png new file mode 100644 index 0000000..39dc2ff --- /dev/null +++ b/plots/HadCRUT5-global-threshold-1880-1920.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0ee7608d8295ea1ab2be1342e714956ce3cfefa5ad0c7f77ae5194c870e2d13 +size 47709 From 1454147c87fdabf9e4fc9b433d55e3e81dfe2887 Mon Sep 17 00:00:00 2001 From: Davide Madrisan Date: Sat, 15 Nov 2025 15:04:34 +0100 Subject: [PATCH 2/3] fix(hadcrut5lib): fix the display of copyright and e-mail Signed-off-by: Davide Madrisan --- hadcrut5lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadcrut5lib.py b/hadcrut5lib.py index 1a84c62..68abfd1 100755 --- a/hadcrut5lib.py +++ b/hadcrut5lib.py @@ -33,7 +33,7 @@ def copyleft(descr: str) -> str: """Print the Copyright message and License""" return ( f"{descr} v{__version__} ({__status__})\n" - "{__copyright__} <{__email__}>\nLicense: {__license__}" + f"{__copyright__} <{__email__}>\nLicense: {__license__}" ) From a0d82fb1085e71c0bed095a71c07a800a0b54170 Mon Sep 17 00:00:00 2001 From: Davide Madrisan Date: Sat, 15 Nov 2025 18:07:10 +0100 Subject: [PATCH 3/3] fix: fix two issues spotted by pylint Signed-off-by: Davide Madrisan --- hadcrut5_close.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hadcrut5_close.py b/hadcrut5_close.py index f52942e..d3ac94a 100755 --- a/hadcrut5_close.py +++ b/hadcrut5_close.py @@ -94,13 +94,12 @@ def plotline(hc5: HadCRUT5, region: str, outfile: str, threshold): ) ymin = min(mean) - ymax = max(mean) plt.imshow( np.linspace(0, 1, 256).reshape(-1, 1), origin="lower", aspect="auto", cmap="coolwarm", - extent=[years[0], years[-1], ymin, 2.0], + extent=(years[0], years[-1], ymin, 2.0), ) plt.fill_between(years, ymin, mean, color="w")