CAMMAC https://cammac.readthedocs.io

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

Build a figure showing change for three SSPs and two (plain or derived) variables

Here applied to : #dry days per year and daily precip for rainy days

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
figure_name          = "Fig8-17" # Used for a symbolic link to an explicit filename,and for metadata filename
version              = ""        # Suffix added to figure name
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 and comprehensive schemes : threshold on cross-model change sign agreeement fraction
same_models_for_var  = False
title                = "Multi-model annual mean long-term changes in daily precipitation statistics"
#
outdir               = "./figures/" # Used for automatic figure name


cases               = {
    "dry"   : {"derivation":"dry"  , "variable":"pr", "table":"day", "threshold": None, 
               "plot_args" :{ "color":"AR6_Evap_12", "units":"days", 
                              "colors":"-32 -16 -8 -4 -2 0 2 4 8 16 32",
                              "focus":"land" }},
    
    "drain" : {"derivation":"drain", "variable":"pr", "table":"day", "threshold": None, 
               "plot_args":{ "color":"AR6_Precip_12", "units":"mm", "scale":24.*3600., 
                             "colors":"-2 -1 -0.5 -0.2 -0.1 0 0.1 0.2 0.5 1 2 ",
                             "focus":'land'}
              },
    "ydry"   : {"derivation":"plain" , "variable":"dday", "table":"yr", "threshold": None, 
               "plot_args" :{ "color":"AR6_Evap_12", "units":"days", 
                              "colors":"-32 -16 -8 -4 -2 0 2 4 8 16 32",
                              "focus":"land" }},
    
    "ydrain" : {"derivation":"plain" , "variable":"drain", "table":"yr", "threshold": None, 
               "plot_args":{ "color":"AR6_Precip_12", "units":"mm", "scale":24.*3600., 
                             "colors":"-2 -1 -0.5 -0.2 -0.1 0 0.1 0.2 0.5 1 2 ",
                             "focus":'land'}
              }
    }


order              = ["dry","ydry"]

ref_experiment     = "historical"
experiments        = ["ssp126","ssp245","ssp585"]
ref_period         = "1995-2014"
proj_period        = "2081-2100"
field_type         = "mean_change"
season             = "ANN"
#
outdir             = "./figures"
common_grid        = "r360x180"
variab_sampling_args={"house_keeping":True,"compute":True,"detrend":True,\
                      "shift":100,"nyears":20,"number":20}

data_versions_tag  = "20200918_plus_derived"
data_versions_dir  = os.getenv("CAMMAC")+"/data"
# As of 16 april 2020, some data for tag 20200219 did disappear from disks at Ciclad:
#excluded_models   = ["BCC-CSM2-MR","EC-Earth3-Veg","GFDL-ESM4","EC-Earth3"]  # seulement sur ssp126 pour le dernier
excluded_models   = []
included_models   = None
variability_excluded_models = []
variability_models= None

# If pre-computed fields for these SSPs, seasons and projection_period are available, should we use it ?
# Set it to False for recomputing either :
#   - for printing fields and field changes statistics
#   - or if any external script launched by CliMAF was internally changed
use_cached_proj_fields = True   
drop_old_figures       = False
print_statistics       = True
#
cache_dir              = "./cache"
figure_details         = {"page_width":2450,"page_height":3444, "insert_width":2400,"pt":55, \
                          "ybox":133,"y":40}
common_grid            = "r360x180"
#
do_test              = True
In [ ]:
if do_test :
    version             = "_test"
    proj_period         = "2099-2100"
    ref_period          = "2013-2014" 
    included_models     = ["CNRM-CM6-1"]    
    variability_models  = ["CNRM-CM6-1"]    
    #cases               = {    "dry"   : {"derivation":"dry"  , "variable":"pr", "table":"day", 
    #                       "plot_args" :{ "color":"AR6_Evap_12", "units":"days", "colors":"-32 -16 -8 -4 -2 0 2 4 8 16 32", "focus":"land" }},}
    order              = ["dry","ydry"]
    experiments        = ["ssp126","ssp126","ssp126"]
    variab_sampling_args={"house_keeping":True,"compute":True,"detrend":True,"shift":100,"nyears":3,"number":3}




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

Libraries

In [ ]:
import sys

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

from CAMMAClib.changes    import change_figure_with_caching
from CAMMAClib.ancillary  import extract_labelbar, prettier_label, create_labelbar2
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 all values by combining global variables and arguments values

In [ ]:
def afigure(experiment,label,title,panel,labelbar="False",outfile=None):
    
    global metadata
    
    variable         = cases[label]["variable"]
    table            = cases[label]["table"]
    derivation_label = cases[label]["derivation"]
    #derivation_label = "plain"
    custom_plot      = cases[label]["plot_args"]
    threshold        = cases[label]["threshold"]
    
    fil,fig,_,variab_models,models = change_figure_with_caching(
        variable, experiment, season,
        data_versions_tag, data_versions_dir=data_versions_dir,
        ref_period=ref_period, proj_period=proj_period, 
        ref_experiment=ref_experiment,
        table=table, 
        field_type=field_type,
        derivation_label=derivation_label,
        title=title, 
        custom_plot=custom_plot, labelbar=labelbar, 
        outdir=outdir, outfile=outfile,
        #
        common_grid=common_grid, 
        variab_sampling_args=variab_sampling_args,
        excluded_models=excluded_models, models=included_models,
        variability_models=variability_models,
        variability_excluded_models=variability_excluded_models,
        cache_dir=cache_dir, read=use_cached_proj_fields, write=True, 
        print_statistics=print_statistics, deep=None,
        threshold=threshold, scheme=scheme, drop=drop_old_figures,
        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([experiment,ref_experiment],models,       variable,table,data_versions,panel)
        metadata+=TSU_metadata(["piControl"]              ,variab_models,variable,table,data_versions,panel)

    return fil,fig

Compute figures for the three experiments and two seasons

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

for exp in experiments :
    figs[exp]=dict()
    files[exp]=dict()
    for label in order:
        ptitle="(%s) %s %s"%(letters[number],prettier_label.get(exp,exp),prettier_label.get(label,label))
        files[exp][label],figs[exp][label] = afigure(exp,label,ptitle,letters[number])
        if drop_old_figures :
            cdrop(figs[exp][label])
        number+=1

Write metadata file

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 common labelbar and assemble it with plots

In [ ]:
### create a figure wih labelbar (using same plot settings as for figures above)
os.system('rm ./fig_with_label_0.png')
labelbar_file_0,_=afigure(experiments[0],order[0],"some title", None, labelbar="True",outfile="./fig_with_label_0.png")

# create a figure wih labelbar (using same plot settings as for figures above)
labelbar_file_1,_=afigure(experiments[0],order[1],"some title", None, labelbar="True",outfile="./fig_with_label_1.png")

create_labelbar2(labelbar_file_0,labelbar_file_1,"./insert.png",missing=False,scheme=scheme)
#os.system("rm ./fig_with_label*.png")

# Create multi-panel figure
page=cpage([
    [figs[experiments[0]][order[0]],figs[experiments[0]][order[1]]],
    [figs[experiments[1]][order[0]],figs[experiments[1]][order[1]]],
    [figs[experiments[2]][order[0]],figs[experiments[2]][order[1]]],
    ],
    title=title,
    insert="./insert.png",
    **figure_details
    )
outfile="change_3SSPS_2variables_%s_%s_%s%s.png"%(data_versions_tag,order[0],order[1],version)
if drop_old_figures :
    cdrop(page)
cfile(page,outdir+"/"+outfile)
os.system("cd %s ; ln -sf %s %s%s.png"%(outdir,outfile,figure_name,version))
os.system("rm ./insert*.png")
#
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))
#

If using a notebook , display result on-line

In [ ]:
#Image(outfile,width=300)