Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding figures of Bock and Lauer (2024) #3526

Open
wants to merge 133 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
133 commits
Select commit Hold shift + click to select a range
20fcd4b
set of new diags and recipes
LisaBock Mar 18, 2022
cb73ec1
extend model list
LisaBock Mar 24, 2022
ca265ae
update model lsit
LisaBock Apr 5, 2022
bc3567a
compute cloud feedback
LisaBock Apr 8, 2022
279e84a
Merge remote-tracking branch 'origin/main' into cloud_ecs_eval
LisaBock Apr 8, 2022
7c5cb43
clean recipe
LisaBock Apr 8, 2022
014f85a
Merge remote-tracking branch 'origin/main' into clouds_ecs_eval
LisaBock Apr 26, 2022
e165f51
fix recip and diag
LisaBock May 3, 2022
ca099ba
Merge remote-tracking branch 'origin/main' into clouds_ecs_eval
LisaBock May 3, 2022
b20fd63
add feedback calculations
LisaBock May 4, 2022
ec8d2cb
add plots for each model
LisaBock May 4, 2022
5b0b1c4
add diag for maps
LisaBock May 4, 2022
da66e26
add single model calc and delte T to height map
LisaBock May 10, 2022
fc2dcc2
add mmm calculation
LisaBock May 11, 2022
8f64c2e
Merge remote-tracking branch 'origin/main' into clouds_ecs_eval
LisaBock May 11, 2022
a356c10
clean recipe
LisaBock May 12, 2022
9ea6690
add temperature change
LisaBock May 23, 2022
f6caeab
mv recipes
LisaBock May 25, 2022
504a54b
create feddback plots
LisaBock May 25, 2022
5cc209b
Merge remote-tracking branch 'origin/main' into clouds_ecs_eval
LisaBock May 25, 2022
d143eae
first draft of scatterplot figure
LisaBock Jun 9, 2022
1550b73
fix diag
LisaBock Jun 14, 2022
665cef5
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Jun 27, 2022
35478d0
continue with scatterplot
LisaBock Jun 28, 2022
9216921
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Jun 28, 2022
95bbfa6
ecs feedback scatter plot
LisaBock Jul 1, 2022
8d1825d
modify threshold
LisaBock Jul 1, 2022
15f35ae
fix height line plot
LisaBock Jul 5, 2022
8f65b61
Allowed usage of create_barplot.py withouth groups
schlunma Jul 8, 2022
408cd1a
Merge remote-tracking branch 'public/expand_barplot' into clouds_ecs_…
LisaBock Jul 8, 2022
514a3a4
add barplot
LisaBock Jul 11, 2022
a10055c
Merge remote-tracking branch 'public/main' into expand_barplot
schlunma Jul 11, 2022
2d07f69
Added option to group bars by color
schlunma Jul 11, 2022
b1c59e7
Merge remote-tracking branch 'public/expand_barplot' into clouds_ecs_…
LisaBock Jul 11, 2022
356f275
add statistics to lat lon plot
LisaBock Jul 27, 2022
4c8f4ab
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Aug 18, 2022
82b000e
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Aug 23, 2022
69f96a4
clean diag
LisaBock Sep 27, 2022
baba88e
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Sep 27, 2022
a8b922c
change threshold
LisaBock Oct 12, 2022
1914d42
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Dec 13, 2022
4b6a129
update zonal height figure
LisaBock Dec 15, 2022
422c2f2
update diag
LisaBock Dec 20, 2022
3884e9f
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Jan 18, 2023
57c4579
add panel numbers
LisaBock Jan 19, 2023
b19ce70
add region boxplots
LisaBock Jan 24, 2023
2b2cf3b
refine boxplot
LisaBock Jan 26, 2023
3789e36
add statistics to lat lon plot
LisaBock Jan 26, 2023
71f345a
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Jan 26, 2023
5402e87
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Jan 27, 2023
7cb757c
add diff plot
LisaBock Jan 27, 2023
ae3ff1e
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Jan 27, 2023
df3996e
add regions
LisaBock Jan 31, 2023
c419eb3
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Jan 31, 2023
f187d50
add bootstrapping
LisaBock Feb 9, 2023
29222be
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Feb 9, 2023
584d799
add corr figure
LisaBock Feb 13, 2023
05baa01
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Feb 13, 2023
ebaa9e1
add corr plot diag
LisaBock Feb 16, 2023
3b2248a
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Feb 22, 2023
2b67cba
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Mar 2, 2023
04a31bf
fix sign of netcre
LisaBock Mar 3, 2023
9fdebd3
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Mar 3, 2023
3c2a037
output of p value
LisaBock Mar 3, 2023
8acf3e0
add y_range to recipe
LisaBock Mar 8, 2023
35db129
add sorting by tag to patterncor
LisaBock Mar 8, 2023
fd6eadf
changed alt obs for pr
LisaBock Mar 10, 2023
06f46f7
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock May 11, 2023
5165aee
modify title and mask invalid data
LisaBock Jun 12, 2023
f3e73d9
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Aug 11, 2023
9da018b
fix order
LisaBock Aug 11, 2023
a0bdf1c
update corr pattern
LisaBock Aug 11, 2023
4676ba0
try CloudSat
LisaBock Aug 16, 2023
940667a
change x and y axes
LisaBock Sep 21, 2023
2035512
change clivi to iwp
LisaBock Sep 21, 2023
bf1e4d2
add y_range to scatterplot
LisaBock Sep 21, 2023
d5a504e
add y_range to scatterplot
LisaBock Sep 21, 2023
4992820
update CERES EBAF
LisaBock Sep 25, 2023
1aad304
fix output
LisaBock Sep 26, 2023
f2a9fff
fix recipe
LisaBock Sep 27, 2023
2800ab9
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Nov 13, 2023
ab1fde1
changes for revision
LisaBock Nov 16, 2023
6f353d9
add combined stratocumulus region
LisaBock Nov 29, 2023
f942688
amip map plot
LisaBock Dec 20, 2023
992835f
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Feb 9, 2024
17e1507
rm files not used
LisaBock Feb 9, 2024
d06befc
reset corr pattern diag changes
LisaBock Feb 9, 2024
dbe54fe
add reference file
LisaBock Feb 9, 2024
29a4dad
recipe and diag for Fig. 3 and 4
LisaBock Feb 9, 2024
a3e9d7b
delete old recipe and diags
LisaBock Feb 12, 2024
ffca87e
solve first codacy issues
LisaBock Feb 12, 2024
ed24edc
add fig5 recipe
LisaBock Feb 12, 2024
f4b5941
fix figure number
LisaBock Feb 12, 2024
e1e24aa
fix provenance
LisaBock Feb 12, 2024
15ab105
add fig 6 diag
LisaBock Feb 12, 2024
e790959
clean recipe
LisaBock Feb 12, 2024
6fc0d06
fix codacy
LisaBock Feb 12, 2024
a0b472b
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Feb 12, 2024
4c54bf2
delete old files
LisaBock Feb 12, 2024
58df927
add fig7 recipe
LisaBock Feb 12, 2024
d847cd3
add fig7 recipe and diag
LisaBock Feb 12, 2024
6617fd3
fix style
LisaBock Feb 12, 2024
fb01901
fix diag name
LisaBock Feb 14, 2024
2bf60fa
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Feb 29, 2024
d4ab57e
add provenance for Fig. 7
LisaBock Mar 1, 2024
69255d9
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Apr 18, 2024
622df63
initial doc file
LisaBock Apr 18, 2024
49b96c4
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Apr 23, 2024
a542647
add recipe for Fig 1 and 2
LisaBock Apr 23, 2024
9cff578
update docu
LisaBock Apr 23, 2024
cc9b385
add docu figure
LisaBock Apr 23, 2024
eccf84e
add doc for Fig 1 and Fig 2
LisaBock Apr 24, 2024
7c0078c
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Apr 24, 2024
4dab805
remove fig 1 and 2 from this branch
LisaBock Apr 24, 2024
91a5e5b
rm fig 1 and 2 from the docu
LisaBock Apr 24, 2024
7b96b5d
add 2 figures to docu
LisaBock Apr 30, 2024
da6cd37
fix captions in docu
LisaBock Apr 30, 2024
a5a1a34
fix style
LisaBock Apr 30, 2024
0c18d63
fix style
LisaBock Apr 30, 2024
cd35b6a
fix style
LisaBock Apr 30, 2024
0666c4b
fix style
LisaBock Apr 30, 2024
5a9a258
fix style
LisaBock Apr 30, 2024
479202d
fix style
LisaBock Apr 30, 2024
25bd9f1
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock May 8, 2024
119cfa9
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Sep 23, 2024
a0aab56
comment lwp and iwp
LisaBock Sep 23, 2024
bfb3352
update
LisaBock Sep 23, 2024
9336f3d
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Sep 23, 2024
c06b07a
fix coding issues
LisaBock Sep 23, 2024
3f32b5d
fix coding issues
LisaBock Sep 24, 2024
19a7879
automated fixes
LisaBock Sep 24, 2024
a24cb7b
Merge remote-tracking branch 'public/main' into clouds_ecs_eval
LisaBock Sep 24, 2024
4ffeaa5
try to fix doc
LisaBock Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions doc/sphinx/source/recipes/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Future projections
recipe_tcr
recipe_tebaldi21esd
recipe_climate_change_hotspot
recipe_bock24acp

IPCC
^^^^
Expand Down
142 changes: 142 additions & 0 deletions doc/sphinx/source/recipes/recipe_bock24acp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
.. _recipes_bock24acp:

Cloud properties and their projected changes in CMIP models with low to high climate sensitivity
================================================================================================

Overview
--------

The recipes recipe_bock24acp_*.yml reproduce figures (Fig. 3, 4, 6 and 7) from the publication Bock and Lauer, 2024.


Available recipes and diagnostics
---------------------------------

Recipes are stored in recipes/clouds

* recipe_bock24acp_fig3-4_maps.yml
* recipe_bock24acp_fig6_zonal.yml
* recipe_bock24acp_fig7_boxplots.yml

Diagnostics are stored in diag_scripts/

Fig. 3 and 4:

* clouds/clouds_ecs_groups_maps.py: Geographical maps of the multi-year annual means for group means of historical CMIP simulations from all three ECS groups.

Fig. 6:

* clouds/clouds_ecs_groups_zonal.py: Zonally averaged group means.

Fig. 7:

* clouds/clouds_ecs_groups_boxplots.py: Boxplots of relative changes for all groups.


User settings in recipe
-----------------------

#. Script clouds_ecs_groups_maps.py

*Required settings (scripts)*

reference: if true, a reference dataset is given within 'variable_group' equal 'OBS'

*Optional settings (scripts)*

plot_each_model: one figure for each single model


#. Script clouds/clouds_ecs_groups_zonal.py

*Required settings (scripts)*

group_by: list of 'variable_group's to have the order
plot_type: 'zonal' and 'height' plots are available

*Optional settings (scripts)*

filename_attach: attachment to the output files


#. Script clouds/clouds_ecs_groups_boxplots.py

*Required settings (scripts)*

exclude_datasets: list of datasets which are not used for the statistics, default is ['MultiModelMean', 'MultiModelP5', 'MultiModelP95']
group_by: list of 'variable_group's to have the order
plot_type: 'zonal' and 'height' plots are available

*Optional settings (scripts)*

filename_attach: attachment to the output files
title: set title of figure
y_range: set range of the y-axes


Variables
---------

* clt (atmos, monthly, longitude latitude time)
* iwp (atmos, monthly, longitude latitude time)
* lwp (atmos, monthly, longitude latitude time)
* rlut (atmos, monthly, longitude latitude time)
* rsut (atmos, monthly, longitude latitude time)
* rlutcs (atmos, monthly, longitude latitude time)
* rsutcs (atmos, monthly, longitude latitude time)
* tas (atmos, monthly, longitude latitude time)


Observations and reformat scripts
---------------------------------

* CERES-EBAF - CERES TOA radiation fluxes (used for calculation of
cloud forcing)

*Reformat script:* cmorizers/data/formatters/datasets/ceres_ebaf.py


References
----------

* Bock, L. and Lauer, A.: Cloud properties and their projected changes in CMIP
models with low to high climate sensitivity, Atmos. Chem. Phys., 24, 1587–1605,
https://doi.org/10.5194/acp-24-1587-2024, 2024.


Example plots
-------------

.. _fig_bock24acp_1:
.. figure:: /recipes/figures/bock24acp/map_netcre.png
:align: center

Geographical map of the multi-year annual mean net cloud radiative effect from
(a) CERES–EBAF Ed4.2 (OBS) and (b–d) group means of historical CMIP simulations
from all three ECS groups (Fig. 4).

.. _fig_bock24acp_2:
.. figure:: /recipes/figures/bock24acp/zonal_diff_clt_ssp585.png
:align: center

The upper panel show the zonally averaged group means of total cloud
fraction from historical simulations (solid lines)
and RCP8.5/SSP5-8.5 scenarios (dashed lines) for the three different ECS groups.
Lower panels show the corresponding relative differences of all zonally
averaged group means between the RCP8.5/SSP5-8.5 scenarios and the corresponding
historical simulations. Shading indicates the 5 % and 95 % quantiles of the single
model results (Fig. 6a).

.. _fig_bock24acp_3:
.. figure:: /recipes/figures/bock24acp/boxplot_ssp585_south_oc.png
:align: center

Relative change (calculated as the difference between the scenario value and the
historical value divided by the historical value) of total cloud fraction (clt),
ice water path (iwp), liquid water path (lwp), and net cloud radiative effect
(netcre) per degree of warming averaged over the Southern Ocean (30–65∘ S). In the
box plot, each box indicates the range from the first
quartile to the third quartile, the vertical line shows the median, and the
whiskers the minimum and maximum values, excluding the outliers. Outliers are
defined as being outside 1.5 times the interquartile range (Fig. 7b).

245 changes: 245 additions & 0 deletions esmvaltool/diag_scripts/clouds/clouds_ecs_groups_boxplots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
"""Python diagnostic for plotting boxplots for different regions."""
import logging
from pathlib import Path

import iris
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

from esmvaltool.diag_scripts.shared import (
ProvenanceLogger,
group_metadata,
run_diagnostic,
get_diagnostic_filename,
get_plot_filename,
select_metadata,
)

logger = logging.getLogger(Path(__file__).stem)

VAR_NAMES = {
'cl': 'cloud_fraction',
'cli': 'ice_water_content',
'clw': 'liquid_water_content',
}
PALETTE = {
'high ECS': 'royalblue',
'med ECS': 'green',
'low ECS': 'orange',
}


def get_provenance_record(ancestor_files):
"""Create a provenance record describing the diagnostic data and plot."""
caption = ("Relative change per degree of warming averaged over the"
"chosen region.")

record = {
'caption': caption,
'statistics': ['mean'],
'domains': ['global'],
'plot_types': ['zonal'],
'authors': [
'bock_lisa',
],
'references': [
'bock24acp',
],
'ancestors': ancestor_files,
}
return record


def _get_multi_model_mean(cubes, var):
"""Compute multi-model mean."""

logger.debug("Calculating multi-model mean")
dataset_names = []
mmm = {}
for (dataset, cube) in cubes.items():
dataset_names.append(dataset)
mmm['dataset'] = cube.data
mmm = np.ma.masked_invalid(list(mmm.values()))
mmm_cube = cube.copy(data=np.ma.mean(mmm, axis=0))
attributes = {
'dataset': 'MultiModelMean',
'short_name': var,
'datasets': '|'.join(dataset_names),
}
mmm_cube.attributes = attributes
return mmm_cube


def read_data(filename):
"""Compute an example diagnostic."""
logger.debug("Loading %s", filename)
cube = iris.load_cube(filename)

if cube.var_name == 'cli':
cube.convert_units('g/kg')
elif cube.var_name == 'clw':
cube.convert_units('g/kg')

cube = iris.util.squeeze(cube)
return cube


def compute_diff(filename1, filename2):
"""Compute difference between two cubes."""
logger.debug("Loading %s", filename1)
cube1 = iris.load_cube(filename1)
cube2 = iris.load_cube(filename2)

if cube1.var_name == 'cli':
cube1.convert_units('g/kg')
cube2.convert_units('g/kg')
elif cube1.var_name == 'clw':
cube1.convert_units('g/kg')
cube2.convert_units('g/kg')

cube = cube2 - cube1
cube.metadata = cube1.metadata
return cube


def compute_diff_temp(input_data, group, var, dataset):
"""Compute relative change per temperture change."""

dataset_name = dataset['dataset']
var = dataset['short_name']

input_file_1 = dataset['filename']

var_data_2 = select_metadata(input_data,
short_name=var,
dataset=dataset_name,
variable_group=var+"_"+group[1])
if not var_data_2:
raise ValueError(
f"No '{var}' data for '{dataset_name}' in '{group[1]}' available")

input_file_2 = var_data_2[0]['filename']

tas_data_1 = select_metadata(input_data,
short_name='tas',
dataset=dataset_name,
variable_group='tas_'+group[0])
tas_data_2 = select_metadata(input_data,
short_name='tas',
dataset=dataset_name,
variable_group='tas_'+group[1])
if not tas_data_1:
raise ValueError(
f"No 'tas' data for '{dataset_name}' in '{group[0]}' available")
if not tas_data_2:
raise ValueError(
f"No 'tas' data for '{dataset_name}' in '{group[1]}' available")
input_file_tas_1 = tas_data_1[0]['filename']
input_file_tas_2 = tas_data_2[0]['filename']

cube = read_data(input_file_1)

cube_diff = compute_diff(input_file_1, input_file_2)
cube_tas_diff = compute_diff(input_file_tas_1, input_file_tas_2)

cube_diff = (100. * (cube_diff / iris.analysis.maths.abs(cube))
/ cube_tas_diff)

return cube_diff


def create_data_frame(input_data, cfg):
"""Create data frame."""
data_frame = pd.DataFrame(columns=['Variable', 'Group', 'Dataset', 'Data'])

ifile = 0

all_vars = group_metadata(input_data, 'short_name')
groups = group_metadata(input_data, 'variable_group', sort='dataset')

for var in all_vars:
if var != 'tas':
logger.info("Processing variable %s", var)

if var == 'clivi':
varname = 'iwp'
else:
varname = var

for group_names in cfg['group_by']:
logger.info("Processing group %s of variable %s",
group_names[0], var)

for dataset in groups[var + "_" + group_names[0]]:
dataset_name = dataset['dataset']

if dataset_name not in cfg['exclude_datasets']:
cube_diff = compute_diff_temp(input_data, group_names,
var, dataset)

group_name = group_names[0].split('_')[1] + " ECS"

data_frame.loc[ifile] = [varname, group_name,
dataset_name, cube_diff.data]
ifile = ifile + 1

data_frame['Data'] = data_frame['Data'].astype(str).astype(float)

return data_frame


def plot_boxplot(data_frame, cfg):

sns.set_style('darkgrid')
sns.set(font_scale=2)
sns.boxplot(data=data_frame, x='Variable', y='Data', hue='Group',
palette=PALETTE)
plt.ylabel('Relative change (%/K)')
if 'y_range' in cfg:
plt.ylim(cfg.get('y_range'))
plt.title(cfg['title'])

provenance_record = get_provenance_record(
ancestor_files=cfg['input_files'])

# Save plot
plot_path = get_plot_filename('boxplot' + '_' + cfg['filename_attach'],
cfg)
plt.savefig(plot_path)
logger.info("Wrote %s", plot_path)
plt.close()

with ProvenanceLogger(cfg) as provenance_logger:
provenance_logger.log(plot_path, provenance_record)


def main(cfg):
"""Run diagnostic."""
cfg.setdefault('exclude_datasets', ['MultiModelMean', 'MultiModelP5',
'MultiModelP95'])
cfg.setdefault('title', 'Test')

plt.figure(constrained_layout=True, figsize=(12, 8))

# Get input data
input_data = list(cfg['input_data'].values())

# Create data frame
data_frame = create_data_frame(input_data, cfg)

# Create plot
plot_boxplot(data_frame, cfg)

# Save file
basename = "boxplot_region_" + cfg['filename_attach']
csv_path = get_diagnostic_filename(basename, cfg).replace('.nc', '.csv')
data_frame.to_csv(csv_path)
logger.info("Wrote %s", csv_path)


if __name__ == '__main__':

with run_diagnostic() as config:
main(config)
Loading