From 9437776a4e7614ffd82dc62915a392e9da821b09 Mon Sep 17 00:00:00 2001 From: George Pulickan <> Date: Wed, 9 Oct 2024 12:56:09 +0100 Subject: [PATCH 01/11] Add George's original recipe for sea level seasonal pressure --- docs/source/recipes/plot_19_recipe.py | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 docs/source/recipes/plot_19_recipe.py diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py new file mode 100644 index 0000000000..7efd238b4d --- /dev/null +++ b/docs/source/recipes/plot_19_recipe.py @@ -0,0 +1,70 @@ +import cfplot as cfp +import cf +import numpy as np +import pandas as pd +from datetime import timedelta +import matplotlib.pyplot as plt + +# 1. Load the dataset +file_path = "~/Documents/Datasets/ERA5_monthly_averaged_SST.nc" +f = cf.read(file_path) +sst = f[0] # Select the SST variable + +# Collapse data by area mean (average over spatial dimensions) +am = sst.collapse("area: mean") # equivalent to "X Y: mean" +am.squeeze(inplace=True) + +# Check available coordinates (already found 'dimensioncoordinate0' as the time coordinate) +print("Available coordinates:", am.coordinates()) + +am_data_key = am.coordinate("dimensioncoordinate0", key=True) +am_copy = am.copy().subspace(**{am_data_key: cf.mam()}) +print(am_copy) +exit() +# Retrieve the time coordinate using its internal identifier +am_data = am.coordinate("dimensioncoordinate0") +am_data_copy = am_copy.coordinate("dimensioncoordinate0") +# Convert the time data from 'hours since 1900-01-01' to datetime format +#time_units = time_coord.units +#am_time = time_coord.data +#am_time_datetime = am.subspace(T=cf.dt("2022-12-01 00:00:00")) + +# Convert datetime to numeric values for plotting (e.g., using matplotlib date format) +#am_time_numeric = pd.to_numeric(pd.to_datetime(am_time_datetime)) + +# Extract data and replace missing values +#am_data = am.data +#am_data = np.where(am_data == -32767, np.nan, am_data) + +# Create the line plot using the full dataset with numeric x-axis + + +print(am[:10]) +print(am_data[:10].data.datetime_as_string) + +cfp.gopen(file="Recipe3.png") # Start the plot +cfp.lineplot( + x=am_data, + y=am, + color="blue", + title="Global Average Sea Surface Temperature", + ylabel="Temperature (K)", + xlabel="Time" +) + +cfp.lineplot( + x=am_data_copy, + y=am_copy, + color="red", +) +cfp.gclose() # Finish the plot + + +# Save the plot to a file using matplotlib +plt.savefig("global_avg_sst_plot.png") + +# Show the plot interactively +plt.show() + +print("Plot created and saved successfully.") + From 75741e6cd43f7747a1bd0b21dc73f1560344205a Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Wed, 9 Oct 2024 14:23:28 +0100 Subject: [PATCH 02/11] Add George recipe info & make fixes for original recipe 19 --- docs/source/recipes/plot_19_recipe.py | 60 +++++++-------------------- 1 file changed, 16 insertions(+), 44 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index 7efd238b4d..23a1a12c6b 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -1,3 +1,10 @@ +""" +Recipe 1: Calculating and Plotting Seasonal Mean Pressure at Mean Sea Level + +Objective: Calculate and plot the seasonal mean pressure at mean sea level +from ensemble simulation data for 1941. +""" + import cfplot as cfp import cf import numpy as np @@ -6,65 +13,30 @@ import matplotlib.pyplot as plt # 1. Load the dataset -file_path = "~/Documents/Datasets/ERA5_monthly_averaged_SST.nc" -f = cf.read(file_path) +f = cf.read("~/recipes_break/ERA5_monthly_averaged_SST.nc") sst = f[0] # Select the SST variable # Collapse data by area mean (average over spatial dimensions) am = sst.collapse("area: mean") # equivalent to "X Y: mean" am.squeeze(inplace=True) -# Check available coordinates (already found 'dimensioncoordinate0' as the time coordinate) +# Check available coordinates (already found 'dimensioncoordinate0' as the +# time coordinate) print("Available coordinates:", am.coordinates()) -am_data_key = am.coordinate("dimensioncoordinate0", key=True) -am_copy = am.copy().subspace(**{am_data_key: cf.mam()}) -print(am_copy) -exit() -# Retrieve the time coordinate using its internal identifier -am_data = am.coordinate("dimensioncoordinate0") -am_data_copy = am_copy.coordinate("dimensioncoordinate0") -# Convert the time data from 'hours since 1900-01-01' to datetime format -#time_units = time_coord.units -#am_time = time_coord.data -#am_time_datetime = am.subspace(T=cf.dt("2022-12-01 00:00:00")) - -# Convert datetime to numeric values for plotting (e.g., using matplotlib date format) -#am_time_numeric = pd.to_numeric(pd.to_datetime(am_time_datetime)) - -# Extract data and replace missing values -#am_data = am.data -#am_data = np.where(am_data == -32767, np.nan, am_data) - -# Create the line plot using the full dataset with numeric x-axis - - -print(am[:10]) -print(am_data[:10].data.datetime_as_string) +am_dim_key, am_data = am.coordinate("dimensioncoordinate0", item=True) +am_sub = am.subspace(**{am_dim_key: cf.mam()}) -cfp.gopen(file="Recipe3.png") # Start the plot +cfp.gopen(file="global_avg_sst_plot.png") cfp.lineplot( - x=am_data, - y=am, + am, color="blue", title="Global Average Sea Surface Temperature", ylabel="Temperature (K)", xlabel="Time" ) - cfp.lineplot( - x=am_data_copy, - y=am_copy, + am_sub, color="red", ) -cfp.gclose() # Finish the plot - - -# Save the plot to a file using matplotlib -plt.savefig("global_avg_sst_plot.png") - -# Show the plot interactively -plt.show() - -print("Plot created and saved successfully.") - +cfp.gclose() From 53b981b8669328ee439e129b2d35bb555f48ed12 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Wed, 9 Oct 2024 15:03:14 +0100 Subject: [PATCH 03/11] Update GP recipe 19 to find per-season max and min --- docs/source/recipes/plot_19_recipe.py | 73 +++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index 23a1a12c6b..c96c05dd66 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -17,26 +17,79 @@ sst = f[0] # Select the SST variable # Collapse data by area mean (average over spatial dimensions) -am = sst.collapse("area: mean") # equivalent to "X Y: mean" -am.squeeze(inplace=True) +am_max = sst.collapse("area: maximum") # equivalent to "X Y: mean" +am_min = sst.collapse("area: minimum") # equivalent to "X Y: mean" +#am.squeeze(inplace=True)cf.seasons() +print("AM SEASONAL IS", am_min, am_max) +# REDUCE TO TEST +am_min = am_min[-100:] # final 100 points +am_max = am_max[-100:] # final 100 points # Check available coordinates (already found 'dimensioncoordinate0' as the # time coordinate) -print("Available coordinates:", am.coordinates()) +###print("Available coordinates:", am.coordinates()) + +###am_dim_key, am_data = am.coordinate("dimensioncoordinate0", item=True) +am_sub_1 = am_min.collapse("T: mean", group=cf.mam()) +am_sub_2 = am_min.collapse("T: mean", group=cf.jja()) +am_sub_3 = am_min.collapse("T: mean", group=cf.son()) +am_sub_4 = am_min.collapse("T: mean", group=cf.djf()) +am_sub_5 = am_max.collapse("T: mean", group=cf.mam()) +am_sub_6 = am_max.collapse("T: mean", group=cf.jja()) +am_sub_7 = am_max.collapse("T: mean", group=cf.son()) +am_sub_8 = am_max.collapse("T: mean", group=cf.djf()) + + + +""" +am_sub_1 = am.subspace(**{am_dim_key: cf.mam()}) +am_sub_2 = am.subspace(**{am_dim_key: cf.month(3)}) +am_sub_3 = am.subspace(**{am_dim_key: cf.month(4)}) +am_sub_4 = am.subspace(**{am_dim_key: cf.month(5)}) +am_sub_2 = am_sub_2 - am_sub_1 +am_sub_3 = am_sub_3 - am_sub_1 +am_sub_4 = am_sub_4 - am_sub_1 +""" -am_dim_key, am_data = am.coordinate("dimensioncoordinate0", item=True) -am_sub = am.subspace(**{am_dim_key: cf.mam()}) cfp.gopen(file="global_avg_sst_plot.png") +#cfp.lineplot( +# am, +# color="blue", +# title="Global Average Sea Surface Temperature", +# ylabel="Temperature (K)", +# xlabel="Time" +#) +cfp.lineplot( + am_sub_1, + color="red", +) +cfp.lineplot( + am_sub_2, + color="green", +) cfp.lineplot( - am, + am_sub_3, color="blue", - title="Global Average Sea Surface Temperature", - ylabel="Temperature (K)", - xlabel="Time" ) cfp.lineplot( - am_sub, + am_sub_4, + color="purple", +) +cfp.lineplot( + am_sub_5, color="red", ) +cfp.lineplot( + am_sub_6, + color="green", +) +cfp.lineplot( + am_sub_7, + color="blue", +) +cfp.lineplot( + am_sub_8, + color="purple", +) cfp.gclose() From 3aaaf40e259abbe75bec2f6e414460db5c7c4e6a Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Wed, 9 Oct 2024 16:17:01 +0100 Subject: [PATCH 04/11] Update GP recipe 19 to view interesting window of 1980+ --- docs/source/recipes/plot_19_recipe.py | 104 +++++++++++++++++--------- 1 file changed, 70 insertions(+), 34 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index c96c05dd66..273880fd68 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -19,77 +19,113 @@ # Collapse data by area mean (average over spatial dimensions) am_max = sst.collapse("area: maximum") # equivalent to "X Y: mean" am_min = sst.collapse("area: minimum") # equivalent to "X Y: mean" -#am.squeeze(inplace=True)cf.seasons() print("AM SEASONAL IS", am_min, am_max) -# REDUCE TO TEST -am_min = am_min[-100:] # final 100 points -am_max = am_max[-100:] # final 100 points -# Check available coordinates (already found 'dimensioncoordinate0' as the -# time coordinate) -###print("Available coordinates:", am.coordinates()) +# Reduce all timeseries down to just 1980+ since there are some data +# quality issues before 1970 +am_max = am_max.subspace(T=cf.ge(cf.dt("1980-01-01"))) +am_min = am_min.subspace(T=cf.ge(cf.dt("1980-01-01"))) +print("FINAL FIELDS ARE", am_max, am_min) -###am_dim_key, am_data = am.coordinate("dimensioncoordinate0", item=True) am_sub_1 = am_min.collapse("T: mean", group=cf.mam()) am_sub_2 = am_min.collapse("T: mean", group=cf.jja()) am_sub_3 = am_min.collapse("T: mean", group=cf.son()) am_sub_4 = am_min.collapse("T: mean", group=cf.djf()) + am_sub_5 = am_max.collapse("T: mean", group=cf.mam()) am_sub_6 = am_max.collapse("T: mean", group=cf.jja()) am_sub_7 = am_max.collapse("T: mean", group=cf.son()) am_sub_8 = am_max.collapse("T: mean", group=cf.djf()) +cfp.gopen(rows=2, columns=1, bottom=0.2, file="global_avg_sst_plot.png") -""" -am_sub_1 = am.subspace(**{am_dim_key: cf.mam()}) -am_sub_2 = am.subspace(**{am_dim_key: cf.month(3)}) -am_sub_3 = am.subspace(**{am_dim_key: cf.month(4)}) -am_sub_4 = am.subspace(**{am_dim_key: cf.month(5)}) -am_sub_2 = am_sub_2 - am_sub_1 -am_sub_3 = am_sub_3 - am_sub_1 -am_sub_4 = am_sub_4 - am_sub_1 -""" +# Put maxima subplot at top since these values are higher, given +# increasing x axis +xticks = list(range(1980, 2024)) +xlabels = [None for i in xticks] - -cfp.gopen(file="global_avg_sst_plot.png") -#cfp.lineplot( -# am, -# color="blue", -# title="Global Average Sea Surface Temperature", -# ylabel="Temperature (K)", -# xlabel="Time" -#) +cfp.gpos(1) cfp.lineplot( - am_sub_1, + am_max, + color="grey", + xlabel="", + #xticks=xticks, + #xticklabels=xlabels, +) +cfp.lineplot( + am_sub_5, color="red", + markeredgecolor="red", + marker="o", + xlabel="", + #xticks=xticks, + #xticklabels=xlabels, ) cfp.lineplot( - am_sub_2, + am_sub_6, color="green", + markeredgecolor="green", + marker="o", + xlabel="", + #xticks=xticks, + #xticklabels=xlabels, ) cfp.lineplot( - am_sub_3, + am_sub_7, color="blue", + markeredgecolor="blue", + marker="o", + xlabel="", + #xticks=xticks, + #xticklabels=xlabels, ) cfp.lineplot( - am_sub_4, + am_sub_8, color="purple", + markeredgecolor="purple", + marker="o", + xlabel="", + #xticks=xticks, + #xticklabels=xlabels, ) + +# Minima subplot below the maxima one +cfp.gpos(2) cfp.lineplot( - am_sub_5, + am_min, + color="grey", +) +#cfp.lineplot( +# am, +# color="blue", +# title="Global Average Sea Surface Temperature", +# ylabel="Temperature (K)", +# xlabel="Time" +#) +cfp.lineplot( + am_sub_1, color="red", + markeredgecolor="red", + marker="o" ) cfp.lineplot( - am_sub_6, + am_sub_2, color="green", + markeredgecolor="green", + marker="o" ) cfp.lineplot( - am_sub_7, + am_sub_3, color="blue", + markeredgecolor="blue", + marker="o" ) cfp.lineplot( - am_sub_8, + am_sub_4, color="purple", + markeredgecolor="purple", + marker="o" ) + cfp.gclose() From 1543841d366507b620582a86970ff00460bc64c6 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Wed, 9 Oct 2024 22:31:59 +0100 Subject: [PATCH 05/11] Update GP recipe 19 to consolidate per-season logic --- docs/source/recipes/plot_19_recipe.py | 123 +++++++++----------------- 1 file changed, 40 insertions(+), 83 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index 273880fd68..d8700d6a3c 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -27,105 +27,62 @@ am_min = am_min.subspace(T=cf.ge(cf.dt("1980-01-01"))) print("FINAL FIELDS ARE", am_max, am_min) -am_sub_1 = am_min.collapse("T: mean", group=cf.mam()) -am_sub_2 = am_min.collapse("T: mean", group=cf.jja()) -am_sub_3 = am_min.collapse("T: mean", group=cf.son()) -am_sub_4 = am_min.collapse("T: mean", group=cf.djf()) +# TODO +colours_seasons_map = { + "red": (cf.mam(), "Mean across MAM: March, April and May"), + "blue": (cf.jja(), "Mean across JJA: June, July and August"), + "green": (cf.son(), "Mean across SON: September, October and November"), + "purple": (cf.djf(), "Mean across DJF: December, January and February"), +} -am_sub_5 = am_max.collapse("T: mean", group=cf.mam()) -am_sub_6 = am_max.collapse("T: mean", group=cf.jja()) -am_sub_7 = am_max.collapse("T: mean", group=cf.son()) -am_sub_8 = am_max.collapse("T: mean", group=cf.djf()) - - -cfp.gopen(rows=2, columns=1, bottom=0.2, file="global_avg_sst_plot.png") +cfp.gopen( + rows=2, columns=1, bottom=0.1, top=0.75, file="global_avg_sst_plot.png") # Put maxima subplot at top since these values are higher, given # increasing x axis -xticks = list(range(1980, 2024)) -xlabels = [None for i in xticks] - cfp.gpos(1) +plt.suptitle( + "Global Average Sea Surface Temperature monthly minima\nand maxima " + "including seasonal means of these extrema", + fontsize=18, +) +for colour, season_query in colours_seasons_map.items(): + query_on_season, season_description = season_query + am_sub = am_max.collapse("T: mean", group=query_on_season) + cfp.lineplot( + am_sub, + color=colour, + markeredgecolor=colour, + marker="o", + xlabel="", + label=season_description, + title="Maxima per month or season", + # TODO FONTSIZE HERE + ) cfp.lineplot( am_max, color="grey", xlabel="", - #xticks=xticks, - #xticklabels=xlabels, -) -cfp.lineplot( - am_sub_5, - color="red", - markeredgecolor="red", - marker="o", - xlabel="", - #xticks=xticks, - #xticklabels=xlabels, -) -cfp.lineplot( - am_sub_6, - color="green", - markeredgecolor="green", - marker="o", - xlabel="", - #xticks=xticks, - #xticklabels=xlabels, -) -cfp.lineplot( - am_sub_7, - color="blue", - markeredgecolor="blue", - marker="o", - xlabel="", - #xticks=xticks, - #xticklabels=xlabels, -) -cfp.lineplot( - am_sub_8, - color="purple", - markeredgecolor="purple", - marker="o", - xlabel="", - #xticks=xticks, - #xticklabels=xlabels, + ylabel="Temperature (K)", + label="All months" ) # Minima subplot below the maxima one cfp.gpos(2) +for colour, season_query in colours_seasons_map.items(): + query_on_season, season_description = season_query + am_sub = am_min.collapse("T: mean", group=query_on_season) + cfp.lineplot( + am_sub, + color=colour, + markeredgecolor=colour, + marker="o", + xlabel="", + title="Minima per month or season" + ) cfp.lineplot( am_min, color="grey", ) -#cfp.lineplot( -# am, -# color="blue", -# title="Global Average Sea Surface Temperature", -# ylabel="Temperature (K)", -# xlabel="Time" -#) -cfp.lineplot( - am_sub_1, - color="red", - markeredgecolor="red", - marker="o" -) -cfp.lineplot( - am_sub_2, - color="green", - markeredgecolor="green", - marker="o" -) -cfp.lineplot( - am_sub_3, - color="blue", - markeredgecolor="blue", - marker="o" -) -cfp.lineplot( - am_sub_4, - color="purple", - markeredgecolor="purple", - marker="o" -) cfp.gclose() From 05c8b408e06c44078ea3d197f4b7c1b455678b08 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Wed, 9 Oct 2024 23:30:11 +0100 Subject: [PATCH 06/11] Finalise GP recipe 19 plot and functional code --- docs/source/recipes/plot_19_recipe.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index d8700d6a3c..25e22eb03b 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -18,16 +18,14 @@ # Collapse data by area mean (average over spatial dimensions) am_max = sst.collapse("area: maximum") # equivalent to "X Y: mean" -am_min = sst.collapse("area: minimum") # equivalent to "X Y: mean" -print("AM SEASONAL IS", am_min, am_max) +am_min = sst.collapse("area: minimum") # Reduce all timeseries down to just 1980+ since there are some data # quality issues before 1970 am_max = am_max.subspace(T=cf.ge(cf.dt("1980-01-01"))) am_min = am_min.subspace(T=cf.ge(cf.dt("1980-01-01"))) -print("FINAL FIELDS ARE", am_max, am_min) -# TODO +# TODO COMMENT colours_seasons_map = { "red": (cf.mam(), "Mean across MAM: March, April and May"), "blue": (cf.jja(), "Mean across JJA: June, July and August"), @@ -36,7 +34,7 @@ } cfp.gopen( - rows=2, columns=1, bottom=0.1, top=0.75, file="global_avg_sst_plot.png") + rows=2, columns=1, bottom=0.1, top=0.85, file="global_avg_sst_plot.png") # Put maxima subplot at top since these values are higher, given # increasing x axis @@ -46,6 +44,9 @@ "including seasonal means of these extrema", fontsize=18, ) +# Set limits manually only to allow space so the legend doesn't overlap the +# data, which isn't possible purely from positioning it anywhere +cfp.gset(xmin="1980-01-01", xmax="2022-12-01", ymin=304, ymax=312) for colour, season_query in colours_seasons_map.items(): query_on_season, season_description = season_query am_sub = am_max.collapse("T: mean", group=query_on_season) @@ -54,21 +55,19 @@ color=colour, markeredgecolor=colour, marker="o", - xlabel="", label=season_description, title="Maxima per month or season", - # TODO FONTSIZE HERE ) cfp.lineplot( am_max, color="grey", xlabel="", - ylabel="Temperature (K)", - label="All months" + label="All months", ) # Minima subplot below the maxima one cfp.gpos(2) +cfp.gset(xmin="1980-01-01", xmax="2022-12-01", ymin=269, ymax=272) for colour, season_query in colours_seasons_map.items(): query_on_season, season_description = season_query am_sub = am_min.collapse("T: mean", group=query_on_season) From 24e4f92f3da1fd1f0ab96fcb34dadb8e99827d20 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Thu, 10 Oct 2024 12:11:17 +0100 Subject: [PATCH 07/11] Lint recipe 19: black, isort, flake8 --- docs/source/recipes/plot_19_recipe.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index 25e22eb03b..161f6792fb 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -6,12 +6,10 @@ """ import cfplot as cfp -import cf -import numpy as np -import pandas as pd -from datetime import timedelta import matplotlib.pyplot as plt +import cf + # 1. Load the dataset f = cf.read("~/recipes_break/ERA5_monthly_averaged_SST.nc") sst = f[0] # Select the SST variable @@ -34,7 +32,8 @@ } cfp.gopen( - rows=2, columns=1, bottom=0.1, top=0.85, file="global_avg_sst_plot.png") + rows=2, columns=1, bottom=0.1, top=0.85, file="global_avg_sst_plot.png" +) # Put maxima subplot at top since these values are higher, given # increasing x axis @@ -77,7 +76,7 @@ markeredgecolor=colour, marker="o", xlabel="", - title="Minima per month or season" + title="Minima per month or season", ) cfp.lineplot( am_min, From 9aeadc362315dc6d9301e59be08c8595cb267059 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Thu, 10 Oct 2024 14:59:33 +0100 Subject: [PATCH 08/11] Flesh out literate prog. comments for recipe 19 --- docs/source/recipes/plot_19_recipe.py | 67 ++++++++++++++++++--------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index 161f6792fb..31d61f2599 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -1,29 +1,43 @@ """ -Recipe 1: Calculating and Plotting Seasonal Mean Pressure at Mean Sea Level +Calculate and plotting per-season trends in global sea surface extrema +====================================================================== -Objective: Calculate and plot the seasonal mean pressure at mean sea level -from ensemble simulation data for 1941. +In this recipe we find the area-based extrema of global sea surface +temperature per month and, because it is very difficult to +interpret for trends when in a monthly form, we calculate and plot +on top of this the mean across each season for both the minima and the +maxima. """ +# %% +# 1. Import cf-python, cf-plot and other required packages: import cfplot as cfp import matplotlib.pyplot as plt import cf -# 1. Load the dataset +# %% +# 2. Read the dataset in extract the SST Field from the FieldList: f = cf.read("~/recipes_break/ERA5_monthly_averaged_SST.nc") -sst = f[0] # Select the SST variable +sst = f[0] -# Collapse data by area mean (average over spatial dimensions) -am_max = sst.collapse("area: maximum") # equivalent to "X Y: mean" -am_min = sst.collapse("area: minimum") +# %% +# 3. Collapse data by area extrema (average over spatial dimensions): +am_max = sst.collapse("area: maximum") # equivalent to "X Y: maximum" +am_min = sst.collapse("area: minimum") # equivalent to "X Y: minimum" -# Reduce all timeseries down to just 1980+ since there are some data -# quality issues before 1970 +# %% +# 4. Reduce all timeseries down to just 1980+ since there are some data +# quality issues before 1970 and also this window is about perfect size +# for viewing the trends without the line plot becoming too cluttered: am_max = am_max.subspace(T=cf.ge(cf.dt("1980-01-01"))) am_min = am_min.subspace(T=cf.ge(cf.dt("1980-01-01"))) -# TODO COMMENT +# %% +# 5. Create a mapping which provides the queries we need to collapse on +# the four seasons, along with our description of them, as a value, with +# the key of the string encoding the colour we want to plot these +# trendlines in. This structure will be iterated over to make our plot: colours_seasons_map = { "red": (cf.mam(), "Mean across MAM: March, April and May"), "blue": (cf.jja(), "Mean across JJA: June, July and August"), @@ -31,20 +45,21 @@ "purple": (cf.djf(), "Mean across DJF: December, January and February"), } +# %% +# 6. Create and open the plot file: cfp.gopen( rows=2, columns=1, bottom=0.1, top=0.85, file="global_avg_sst_plot.png" ) -# Put maxima subplot at top since these values are higher, given -# increasing x axis +# %% +# 7. Put maxima subplot at top since these values are higher, given +# increasing x axis. Note we set limits manually with 'gset' only to +# allow space so the legend doesn't overlap the data, which isn't +# possible purely from positioning it anywhere within the default plot. +# Otherwise cf-plot handles this for us. To plot the per-season means +# of the maxima, we loop through the season query mapping and do a +# "T: mean" collapse setting the season as the grouping: cfp.gpos(1) -plt.suptitle( - "Global Average Sea Surface Temperature monthly minima\nand maxima " - "including seasonal means of these extrema", - fontsize=18, -) -# Set limits manually only to allow space so the legend doesn't overlap the -# data, which isn't possible purely from positioning it anywhere cfp.gset(xmin="1980-01-01", xmax="2022-12-01", ymin=304, ymax=312) for colour, season_query in colours_seasons_map.items(): query_on_season, season_description = season_query @@ -64,7 +79,10 @@ label="All months", ) -# Minima subplot below the maxima one +# %% +# 8. Create and add minima subplot below the maxima one. Just like for the +# maxima case, we plot per-season means by looping through the season query +# mapping and doing a "T: mean" collapse setting the season as the grouping: cfp.gpos(2) cfp.gset(xmin="1980-01-01", xmax="2022-12-01", ymin=269, ymax=272) for colour, season_query in colours_seasons_map.items(): @@ -83,4 +101,11 @@ color="grey", ) +# %% +# 9. Add an overall title to the plot and close the file to save it: +plt.suptitle( + "Global Average Sea Surface Temperature monthly minima\nand maxima " + "including seasonal means of these extrema", + fontsize=18, +) cfp.gclose() From bc2030561e83626c9f3d15574588912beae47860 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Thu, 10 Oct 2024 15:15:30 +0100 Subject: [PATCH 09/11] Final pre-review updates for recipe 19 --- docs/source/recipes/plot_19_recipe.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index 31d61f2599..cc8c052493 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -1,6 +1,6 @@ """ -Calculate and plotting per-season trends in global sea surface extrema -====================================================================== +Plotting per-season trends in global sea surface tempreature extrema +==================================================================== In this recipe we find the area-based extrema of global sea surface temperature per month and, because it is very difficult to @@ -19,10 +19,10 @@ # %% # 2. Read the dataset in extract the SST Field from the FieldList: f = cf.read("~/recipes_break/ERA5_monthly_averaged_SST.nc") -sst = f[0] +sst = f[0] # this gives the sea surface temperature (SST) # %% -# 3. Collapse data by area extrema (average over spatial dimensions): +# 3. Collapse the SST data by area extrema (extrema over spatial dimensions): am_max = sst.collapse("area: maximum") # equivalent to "X Y: maximum" am_min = sst.collapse("area: minimum") # equivalent to "X Y: minimum" @@ -38,7 +38,7 @@ # the four seasons, along with our description of them, as a value, with # the key of the string encoding the colour we want to plot these # trendlines in. This structure will be iterated over to make our plot: -colours_seasons_map = { +colours_seasons_mapping = { "red": (cf.mam(), "Mean across MAM: March, April and May"), "blue": (cf.jja(), "Mean across JJA: June, July and August"), "green": (cf.son(), "Mean across SON: September, October and November"), @@ -61,11 +61,11 @@ # "T: mean" collapse setting the season as the grouping: cfp.gpos(1) cfp.gset(xmin="1980-01-01", xmax="2022-12-01", ymin=304, ymax=312) -for colour, season_query in colours_seasons_map.items(): +for colour, season_query in colours_seasons_mapping.items(): query_on_season, season_description = season_query - am_sub = am_max.collapse("T: mean", group=query_on_season) + am_max_collapse = am_max.collapse("T: mean", group=query_on_season) cfp.lineplot( - am_sub, + am_max_collapse, color=colour, markeredgecolor=colour, marker="o", @@ -85,11 +85,11 @@ # mapping and doing a "T: mean" collapse setting the season as the grouping: cfp.gpos(2) cfp.gset(xmin="1980-01-01", xmax="2022-12-01", ymin=269, ymax=272) -for colour, season_query in colours_seasons_map.items(): +for colour, season_query in colours_seasons_mapping.items(): query_on_season, season_description = season_query - am_sub = am_min.collapse("T: mean", group=query_on_season) + am_min_collapse = am_min.collapse("T: mean", group=query_on_season) cfp.lineplot( - am_sub, + am_min_collapse, color=colour, markeredgecolor=colour, marker="o", @@ -104,8 +104,8 @@ # %% # 9. Add an overall title to the plot and close the file to save it: plt.suptitle( - "Global Average Sea Surface Temperature monthly minima\nand maxima " - "including seasonal means of these extrema", + "Global mean sea surface temperature (SST) monthly\nminima and maxima " + "showing seasonal means of these extrema", fontsize=18, ) cfp.gclose() From d39a47d9b9533a3673d971b500f069c391b342b2 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Thu, 10 Oct 2024 15:30:58 +0100 Subject: [PATCH 10/11] Add recipe 19 to recipes listing with filter keywords --- docs/source/recipes/recipe_list.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/recipes/recipe_list.txt b/docs/source/recipes/recipe_list.txt index f39297f9cb..42ccae6c78 100644 --- a/docs/source/recipes/recipe_list.txt +++ b/docs/source/recipes/recipe_list.txt @@ -27,4 +27,6 @@ plot_13_recipe.html#sphx-glr-recipes-plot-13-recipe-py plot_14_recipe.html#sphx-glr-recipes-plot-14-recipe-py
plot_15_recipe.html#sphx-glr-recipes-plot-15-recipe-py -
\ No newline at end of file +
+plot_19_recipe.html#sphx-glr-recipes-plot-19-recipe-py +
From 87a1932382e8872de9a9ceffa9ae91a44fa9a77f Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Thu, 10 Oct 2024 15:49:33 +0100 Subject: [PATCH 11/11] Update docs/source/recipes/plot_19_recipe.py for consistent data path --- docs/source/recipes/plot_19_recipe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/recipes/plot_19_recipe.py b/docs/source/recipes/plot_19_recipe.py index cc8c052493..bcc8f2823f 100644 --- a/docs/source/recipes/plot_19_recipe.py +++ b/docs/source/recipes/plot_19_recipe.py @@ -18,7 +18,7 @@ # %% # 2. Read the dataset in extract the SST Field from the FieldList: -f = cf.read("~/recipes_break/ERA5_monthly_averaged_SST.nc") +f = cf.read("~/recipes/ERA5_monthly_averaged_SST.nc") sst = f[0] # this gives the sea surface temperature (SST) # %%