CAMMAC https://cammac.readthedocs.io

S.Sénési for Météo-France - sept 2019 to march 2021

Build a figure showing changes for three SSPs and the reference field

Here applied to precipitation seasonnality

Parameters stand in first cell, are either commented here or in the doc (see above)

A few commands below are specific to the Notebook environment, and can be safely commented out

Default settings (some may be overriden by Papermill - this would show in next cell in the execution output notebook)

In [ ]:
import os
do_test            = False

figure_name        = "Box8-2_Fig1"
# Version number will be a suffix of figure filename
version            = ""
scheme             = "AR5"
confidence_factor    = 1.645  # For AR6 comprehensive scheme : Multiplicative factor applied to control run 
                              # variability for deciding a change is significant (besides sqrt(2))
sign_threshold       = 0.66   # For AR6 simple scheme : threshold on cross-model change sign agreeement fraction
same_models_for_var= False

title              = None
#
data_versions_tag  = "20200719c"
data_versions_dir  = os.getenv("CAMMAC")+"/data"
excluded_models     = []  
included_models     = None
#
variable           = "pr"
#threshold          = 0.1/(24*3600) # 0.1 mm/day, in SI
threshold          = None
table              = "Amon"
derivation         = "seasonality"
#
experiments        = ["ssp126","ssp245","ssp585"] 
proj_period        = "2081-2100"
ref_experiment     = "historical"
ref_period         = "1995-2014"
# Which is the SSP which models list will be used for computing reference ensemble mean
ssp_for_ref        = "ssp585" 
season             = "ANN"
field_type         = "mean_change"
custom_plot        = {"min":-0.2,"max":0.2, "delta":0.04, "color":"AR6_Temp_12"}
#
use_cached_proj_fields = True
drop_old_figures       = False
use_cached_ref_field   = True
cache_dir          = "./cache/"
figure_details     = {"page_width":2450, "page_height":2450,"insert_width":2400, "pt":55, "ybox":133,"y":40}
common_grid        = "r360x180"
variab_sampling_args = {"house_keeping":True,"compute":True,"detrend":True,"shift":100,"nyears":20,"number":20}
outdir             = "./figures"

# If some basic fields are to be plotted for each model :
##########################################################
#   - which fields should be actually plotted
# plot_for_each_model    = [ "reference", "projection", "change", "rchange", "schange", "variability" ]
plot_for_each_model    = [ ]

#   - and with which common plot_parameters
custom_plot_all_fields = { "proj" : "Robinson", "mpCenterLonF" : 0., "options" : "lbBoxEndCapStyle=TriangleBothEnds", "focus":"land"}

#   - and which range should be used for each field_type
ranges = {}   # The baseline value !
# Values below fit the case of mrso
#ranges={ "reference" : { "min" : 0., "max" : 3000. , "delta" : 200. } ,
#        "projection" : { "min" : 0., "max" : 3000. , "delta" : 200. } ,
#        "change"     : { "min" :1000.,"max":-1000. , "delta":200.} , 
#        "rchange"    : { "min" : -25., "max" : 25. , "delta" : 5. } ,
#        "variability": { "min" : 0., "max" : 1. , "delta" : 0.1 } ,
#       }
In [ ]:
#do_test=True
if do_test :
    version              = "_test"
    proj_period          = "2099-2100"
    ref_period           = "2013-2014" 
    included_models      = ["CNRM-CM6-1"]    
    experiments          = ["ssp126","ssp126","ssp126"]
    ssp_for_ref          = "ssp126"
    variab_sampling_args = {}
    use_cached_proj_fields=True
    use_cached_ref_field = True


    #plot_for_each_model    = [ "reference", "projection", "change", "rchange", "schange", "variability" ]

 Loading libraries

In [ ]:
import sys, os, os.path

from climaf.api import *
climaf.cache.stamping=False

from CAMMAClib.changes    import change_figure_with_caching, change_figure
from CAMMAClib.ancillary  import create_labelbar2, prettier_label
from CAMMAClib.cancillary import walsh_seasonality
from CAMMAClib.mips_et_al import TSU_metadata, read_versions_dictionnary

# Load some user settings, if available
settings_file=os.getenv("CAMMAC_USER_PYTHON_CODE_DIR",".")+'/cammac_user_settings.py'
if os.path.exists(settings_file) :
    exec(compile(open(settings_file).read(),settings_file,'exec'))

If using a notebook, use wide display

In [ ]:
from IPython.core.display import display, HTML, Image
display(HTML("<style>.container { width:100% !important; }</style>"))

The basic engine is function change_figure_with_caching, which has numerous settings

Next function allows to set almost all values

In [ ]:
def afigure(experiment,title,panel,labelbar="False",outfile=None,read=True,
            custom_plot=custom_plot,field_type=field_type):
    
    global metadata
    _,fig,dic,variab_models,models= change_figure_with_caching(
        ref_period=ref_period, proj_period=proj_period, 
        variable=variable, table=table, 
        experiment=experiment, ref_experiment=ref_experiment, season=season,
        derivation_label=derivation, 
        field_type=field_type,
        title=title, 
        custom_plot=custom_plot, labelbar=labelbar, 
        data_versions_tag=data_versions_tag, data_versions_dir=data_versions_dir,
        outdir=outdir, outfile=outfile,
        #
        common_grid=common_grid, 
        variab_sampling_args=variab_sampling_args,
        models=included_models, excluded_models=excluded_models,
        cache_dir=cache_dir, read=read, write=True, 
        print_statistics=True , deep=None,  threshold=threshold,
        drop = drop_old_figures,
        scheme=scheme, same_models_for_variability_and_changes=same_models_for_var,
        low_change_agree_threshold=confidence_factor,
        change_sign_agree_threshold = sign_threshold
        )
    if panel is not None :
        metadata+=TSU_metadata([ref_experiment,experiment],models,variable,table,data_versions,panel)
        if variab_sampling_args != {} :
            metadata+=TSU_metadata(["piControl"],variab_models,variable,table,data_versions,panel)
    return fig,dic,models

Compute figures for the three experiments

In [ ]:
figs=dict()
dics=dict()
files=dict()
number=0
letters=["b","c","d"]
metadata=""
data_versions=read_versions_dictionnary(data_versions_tag, data_versions_dir)

for exp in experiments :
    print("processing "+exp)
    etitle="(%s) %s"%(letters[number],prettier_label.get(exp,exp))
    figs[exp],dic,models = afigure(exp,etitle,letters[number],read=use_cached_proj_fields)
    if dic is not None :
        dics[exp]=dic[exp]
    if drop_old_figures :
        cdrop(figs[exp])
    number+=1
    

Compute and plot reference field models mean

In [ ]:
ref_file="%s/reference_mean_%s_%s_%s.nc"%(cache_dir,variable,derivation,data_versions_tag)
#
rtitle="reference : %s (%s)"%(ref_experiment,ref_period)
if not use_cached_ref_field or not os.path.exists(ref_file):
    _,dic,models = afigure(ssp_for_ref,rtitle,"a",read=False)
    ens=cens()
    #models=dic[ssp_for_ref][season]["reference"][derivation]
    for model,variant in models :
        ens[model]=regridn(dic[ssp_for_ref][season]["reference"][derivation][model],
                           cdogrid=common_grid,option='remapcon')
    ref_mean=ccdo_ens(ens,operator='ensmean')
    cdrop(ref_mean)
    cfile(ref_mean,ref_file)
    #
    ref_metadata=TSU_metadata([ref_experiment],models,variable,table,data_versions,"a")
    metadata+=ref_metadata
    #with open("%s/%s%s_a_md"%(outdir,figure_name,version),"w") as f:   f.write(ref_metadata)
    ref_number=len(models)
else :
    ref_mean=fds(ref_file,period=ref_period,variable=variable)
    ref_number="39"
#
ref_fig=change_figure(variable,derivation,ref_mean,"","",relative=False,
                          labelbar="False",title="a) %s"%rtitle,number=ref_number ) 
if drop_old_figures :
    cdrop(ref_fig)
In [ ]:
import os.path
if not os.path.exists(outdir):
    os.makedirs(outdir)
with open("%s/%s%s_md.txt"%(outdir,figure_name,version),"w")  as f: f.write(metadata)

Create the labelbars, concatenate it, and assemble it with plots

In [ ]:
# create a change figure wih labelbar 
labelbar_figure,_,_=afigure(experiments[0],"some_title", "some panel", 
                            labelbar="True",outfile="./fig_with_label.png")

# create a ref figure wih labelbar and extract labelbar
ref_fig_with_labelbar=change_figure(variable,derivation,ref_mean,"","",relative=False,
                                        labelbar="True",title="some title")
if drop_old_figures :
    cdrop(ref_fig_with_labelbar)
cfile(ref_fig_with_labelbar,"./ref_with_label.png")

# Extract and assemble labelbars
create_labelbar2("./ref_with_label.png", "./fig_with_label.png","./lb2.png",missing=False,scheme=scheme)#,y_offset=580)

if title is None :
    title="Multi-model changes in %s "%prettier_label.get(variable,variable)
    if derivation !=  "plain" :
        title+=derivation+" "
    title+="for "+proj_period

# Create multi-panel figure
page=cpage([
      [ref_fig             , figs[experiments[0]]],
      [figs[experiments[1]], figs[experiments[2]]],
      ],
    title=title,
    insert="./lb2.png", **figure_details
    )
#
outfile="change_3SSPS_plus_ref_%s_%s_%s_%s%s.png"%(variable,derivation,proj_period,data_versions_tag,version)
if drop_old_figures :
    cdrop(page)
print(cfile(page,outdir+"/"+outfile))
os.system("cd %s ; ln -sf %s %s%s.png"%(outdir,outfile,figure_name,version))
#
small=outfile.replace(".png",".small.png")
os.system("cd %s ; convert -geometry 50%% %s %s"%(outdir,outfile,small))
os.system("cd %s ; ln -sf %s %s%s_small.png"%(outdir,small,figure_name,version))
#
os.system("rm -f ./lb2.png")
os.system("rm -f ./*_with_label.png")

If using a notebook , display result on-line

In [ ]:
#Image(outdir+"/"+outfile,width=600)

Plotting all models for all field types and all cases

In [ ]:
if use_cached_proj_fields==True and len(plot_for_each_model) > 0 :
    raise Exception("Cannot plot individual models when running with use_cached_proj_fields=True")
else:
    for field_type in plot_for_each_model :
        #
        plotargs=custom_plot_all_fields.copy()
        plotargs.update(ranges.get(field_type,{}))
        #
        for experiment in experiments : 
            allplots=plot(cens(dics[experiment][season][field_type][derivation]),**plotargs)
            page=cpage(allplots,page_width=1200,page_height=1700,title="%s_%s_%s_%s_%s"%(variable,derivation,field_type,experiment,season))
            pagename="%s/all_models_%s_%s_%s_%s_%s_%s.png"%(outdir,variable,derivation,field_type,experiment,season,data_versions_tag)
            cfile(page,pagename)