In [1]:
from IPython.display import Image
Image(url='https://vesg.ipsl.upmc.fr/thredds/fileServer/IPSLFS/jservon/CliMAF_Notebooks_html/CliMAF-logo-small.png') 
Out[1]:

CliMAF: Climate Model Assessment Framework

A science-oriented framework to ease the analysis of climate model simulations

WP5 ANR Convergence
Development team: Stéphane Sénési (CNRM-GAME), Gaëlle Rigoudy (CNRM-GAME), Jérôme Servonnat (LSCE-IPSL), Ludivine Vignon (CNRM-GAME), Laurent Franchisteguy (CNRM-GAME), Patrick Brockmann (LSCE-IPSL)
Beta-testing: Olivier Marti (LSCE-IPSL), Marie-Pierre Moine (CERFACS), Emilia Sanchez-Gomez (CERFACS)

contact: climaf@meteo.fr
users list: climaf-users@meteo.fr

Getting started with ts_plot()

In [2]:
Image(url='https://vesg.ipsl.upmc.fr/thredds/fileServer/IPSLFS/jservon/CliMAF_Notebooks_html/ts_plot_example.png')
Out[2]:

Outline

    1. basic plot
      • 1.a: Different python objects handled by ts_plot (link with ts_plot doc)
      • 1.b: Change figure size and plot margins
    1. Customize the plot
      • 2.a: edit the titles, labels, and axis
      • 2.b: lines colors, thickness, patterns and transparency
      • 2.c: highlight a period
      • customize the legend: see section 3.c
    1. Plotting multiple lines: an example with an ensemble
      • 3.a: plot an ensemble
      • 3.b: add the ensemble mean and control the colors
      • 3.c: customize the legend

Also see CliMAF documentation on ts_plot:

https://climaf.readthedocs.io/en/master/functions_results_viewing.html?#ts-plot-shortcut-for-ensemble-ts-plot

which is a shortcut for ensemble_ts_plot script:

https://climaf.readthedocs.io/en/master/scripts/ensemble_ts_plot.html

List of all options available

Lines:

  • colors: list of colors
  • lw: lines thicknesses
  • alphas: lines opacity
  • linestyles: lines styles
  • highlight_period: Highlight a period on a time series (thicker line) ; provide the list of periods yearstart_yearend (Ex: ['1980_2005','1990_2000'] to highlight the first period on the first dataset, and the second period on the second dataset)
  • highlight_period_lw: Thickness of the highlighted period
  • time_offset : Add a time offset to the beginning of the time series

General settings:

  • min, max: minimum and maximum value
  • offset, scale: apply an offset and a scale to all your time series
  • xlim: Provide the start date and end date to force the X axis. Ex: 1950-01-01,2005-12-31
  • ylim: Provide the interval for the Y axis
  • xlabel, ylabel: X and Y axis label
  • xlabel_fontsize, ylabel_fontsize: X and Y axis label size
  • tick_size: Ticks size
  • fig_size: Size of the figure in inches => widthheight Ex: 155

Text:

  • text: add some text in the plot; the user provides a triplet separared with commas x,y,text; separate the triplets with | if you want to provide multiple texts. Ex: x1,y1,text1|x2,y2,text2
  • text_fontsize: fontsize of the text (list if more than one)
  • text_colors: color of the text (list if more than one)
  • text_verticalalignment: Vertical alignment of the text (list if more than one)
  • text_horizontalalignment: Horizontal alignment of the text (list if more than one)

Titles:

  • left_string: Left string (used as title by default)
  • right_string: Right string
  • center_string: Center string
  • left_string_fontsize: Left string size
  • right_string_fontsize: Right string size
  • center_string_fontsize: Center string size

Legend:

  • draw_legend: Draw the legend? True/False
  • legend_colors: legend colors separated by commas
  • legend_labels: Labels of the legend
  • legend_xy_pos: x,y Position of the corner of the box (by default = upper left corner). Example= “1.02,1”
  • legend_loc: Choose the corner of the legend box to specify the position of the legend box; by default 2 (upper left corner), take values 1, 2, 3 or 4 (see resource loc of pyplot legend)
  • legend_fontsize: Font size in the legend
  • legend_ncol: Number of columns in the legend
  • legend_frame: Draw the box around the legend? True/False
  • legend_lw: Line widths (provide either one for all, or one by time series separated by commas)
  • append_custom_legend_to_default: Append the custom legend to the default one? True/False

Control margins:

  • left_margin: Position of the left border of the figure in the plot
  • right_margin: Position of the right border of the figure in the plot
  • bottom_margin: Position of the bottom border of the figure in the plot
  • top_margin: Position of the top border of the figure in the plot

Horizontal and vertical lines:

  • horizontal_lines_values: Y values for horizontal lines
  • horizontal_lines_styles: Horizontal lines styles
  • horizontal_lines_lw: Horizontal lines thickness
  • horizontal_lines_colors: Horizontal lines colors
  • vertical_lines_values: Y values for vertical lines
  • vertical_lines_styles: vertical lines styles
  • vertical_lines_lw: vertical lines thickness
  • vertical_lines_colors: vertical lines colors

Import climaf

In [3]:
from climaf.api import *
clog('critical') # min verbosity = critical < warning < info < debug = max verbosity
python => 2.7.15 | packaged by conda-forge | (default, Jul  2 2019, 00:39:44) 
[GCC 7.3.0]
---
Required softwares to run CliMAF => you are using the following versions/installations:
ncl 6.6.2 => /modfs/modtools-phw/miniconda2/envs/analyse_2.7/bin/ncl
cdo 1.9.6 => /opt/nco/1.9/bin/cdo
nco (ncks) 4.5.2 => /opt/nco-4.5.2/bin/ncks
ncdump fichier => /prodigfs/ipslfs/dods/jservon/miniconda/envs/cesmep_env/bin/ncdump
Check stamping requirements
nco (ncatted) found -> /opt/nco-4.5.2/bin/ncatted
convert found -> /usr/bin/convert
pdftk found -> /usr/bin/pdftk
exiv2 found -> /ciclad-home/jservon/Evaluation/CliMAF/climaf_installs/climaf_V2.0.0/bin/exiv2
---
CliMAF install => /ciclad-home/jservon/Evaluation/CliMAF/climaf_installs/climaf_V2.0.0
CliMAF version = 2.0.0
Cache directory set to : /data/jservon/climafcache (use $CLIMAF_CACHE if set) 
Cache directory for remote data set to : /data/jservon/climafcache/remote_data (use $CLIMAF_REMOTE_CACHE if set) 
warning  : When defining temp_penalty : duplicate declaration for input #0
warning  : When defining cquantile : duplicate declaration for input #0
warning  : When defining cquantile : duplicate declaration for input #0
Available macros read from ~/.climaf.macros are : []

0. Get a dataset and compute a global average annual mean time series

In [4]:
dat = ds(project='CMIP5', model='CNRM-CM5', experiment='historical', frequency='monthly', version='v20130101',
         period='1950-2005', variable='tos', realm='ocean' )
ts_dat = ccdo(space_average(dat), operator='yearmean')

1. Basic plot

In this section we will see the basis to draw a time series plot with ts_plot:

-   1.a: Different python objects handled by ts_plot
-   1.b: Change figure size and plot margins

Simple CliMAF object

In [5]:
# -- Trivial example: ts_dat is a CliMAF object
myplot = ts_plot(ts_dat)
iplot(myplot)
Out[5]:
In [6]:
!cat last.out
==> args =  Namespace(alphas='', append_custom_legend_to_default='', bottom_margin='', center_string='', center_string_fontsize='', colors='', draw_legend='', fig_size='', filenames='/data/jservon/climafcache/6a/4725008e5d293469790fa2c0aaed6dc014ef7093c16a47603e9482.nc', highlight_period='', highlight_period_lw='', horizontal_lines_colors='', horizontal_lines_lw='', horizontal_lines_styles='', horizontal_lines_values='', labels='"ccdo(space_average(ds(CMIP5%%tos%1950-2005%global%/bdd%CNRM-CM5%*%historical%r1i1p1%monthly%ocean%v20130101)),operator=yearmean)"', left_margin='', left_string='Sea Surface Temperature', left_string_fontsize='30', legend_colors='', legend_fontsize='', legend_frame='', legend_labels='', legend_loc='', legend_lw='', legend_ncol='', legend_xy_pos='', linestyles='', lw='', max='', min='', offset='-273.15', outfig='/data/jservon/climafcache/75/d24e74bf74bcda03f4c32291ea9d43fc3e186aa8b61a41dca55e64_27813.png', right_margin='', right_string='model = CNRM-CM5', right_string_fontsize='20', scale='', text='', text_colors='', text_fontsize='', text_horizontalalignment='', text_verticalalignment='', tick_size='', time_offset=None, title='', title_fontsize='', top_margin='', variable='tos', vertical_lines_colors='', vertical_lines_lw='', vertical_lines_styles='', vertical_lines_values='', x_axis=u'Real', xlabel='Calendar time', xlabel_fontsize='', xlim='1951-01-01,2006-12-31', ylabel='Temperature (degC)', ylabel_fontsize='', ylim='17.7,18.8')
datevar =  [datetime.datetime(1950, 7, 1, 6, 0), datetime.datetime(1951, 7, 1, 6, 0), datetime.datetime(1952, 7, 1, 6, 0), datetime.datetime(1953, 7, 1, 6, 0), datetime.datetime(1954, 7, 1, 6, 0), datetime.datetime(1955, 7, 1, 6, 0), datetime.datetime(1956, 7, 1, 6, 0), datetime.datetime(1957, 7, 1, 6, 0), datetime.datetime(1958, 7, 1, 6, 0), datetime.datetime(1959, 7, 1, 6, 0), datetime.datetime(1960, 7, 1, 6, 0), datetime.datetime(1961, 7, 1, 6, 0), datetime.datetime(1962, 7, 1, 6, 0), datetime.datetime(1963, 7, 1, 6, 0), datetime.datetime(1964, 7, 1, 6, 0), datetime.datetime(1965, 7, 1, 6, 0), datetime.datetime(1966, 7, 1, 6, 0), datetime.datetime(1967, 7, 1, 6, 0), datetime.datetime(1968, 7, 1, 6, 0), datetime.datetime(1969, 7, 1, 6, 0), datetime.datetime(1970, 7, 1, 6, 0), datetime.datetime(1971, 7, 1, 6, 0), datetime.datetime(1972, 7, 1, 6, 0), datetime.datetime(1973, 7, 1, 6, 0), datetime.datetime(1974, 7, 1, 6, 0), datetime.datetime(1975, 7, 1, 6, 0), datetime.datetime(1976, 7, 1, 6, 0), datetime.datetime(1977, 7, 1, 6, 0), datetime.datetime(1978, 7, 1, 6, 0), datetime.datetime(1979, 7, 1, 6, 0), datetime.datetime(1980, 7, 1, 6, 0), datetime.datetime(1981, 7, 1, 6, 0), datetime.datetime(1982, 7, 1, 6, 0), datetime.datetime(1983, 7, 1, 6, 0), datetime.datetime(1984, 7, 1, 6, 0), datetime.datetime(1985, 7, 1, 6, 0), datetime.datetime(1986, 7, 1, 6, 0), datetime.datetime(1987, 7, 1, 6, 0), datetime.datetime(1988, 7, 1, 6, 0), datetime.datetime(1989, 7, 1, 6, 0), datetime.datetime(1990, 7, 1, 6, 0), datetime.datetime(1991, 7, 1, 6, 0), datetime.datetime(1992, 7, 1, 6, 0), datetime.datetime(1993, 7, 1, 6, 0), datetime.datetime(1994, 7, 1, 6, 0), datetime.datetime(1995, 7, 1, 6, 0), datetime.datetime(1996, 7, 1, 6, 0), datetime.datetime(1997, 7, 1, 6, 0), datetime.datetime(1998, 7, 1, 6, 0), datetime.datetime(1999, 7, 1, 6, 0), datetime.datetime(2000, 7, 1, 6, 0), datetime.datetime(2001, 7, 1, 6, 0), datetime.datetime(2002, 7, 1, 6, 0), datetime.datetime(2003, 7, 1, 6, 0), datetime.datetime(2004, 7, 1, 6, 0), datetime.datetime(2005, 7, 1, 6, 0)]
lw_list[dataset_number] 0.4
colors[dataset_number] royalblue
linestyles_list[dataset_number] solid
alphas_list[dataset_number] 1
dataset_numb : 0
lw_list : 0
lw_list : (1,)
color : royalblue
labels : ccdo(space_average(ds(CMIP5%%tos%1950-2005%global%/bdd%CNRM-CM5%*%historical%r1i1p1%monthly%ocean%v20130101)),operator=yearmean)
nctime : 36705.25
nctime : (56,)
nctime : <type 'numpy.float64'>
X : 1950-07-01 06:00:00
X : (56,)
X : <type 'datetime.datetime'>
Y : 18
Y : <type 'int'>
leg_dict =  {'loc': 2, 'bbox_to_anchor': (1.02, 1.0), 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False, 'prop': {u'size': 12.0}}
/data/jservon/climafcache/75/d24e74bf74bcda03f4c32291ea9d43fc3e186aa8b61a41dca55e64_27813.png


stdout and stderr of script call :
	 python /ciclad-home/jservon/Evaluation/CliMAF/climaf_installs/climaf_V2.0.0/climaf/../scripts/ensemble_time_series_plot.py --filenames="/data/jservon/climafcache/6a/4725008e5d293469790fa2c0aaed6dc014ef7093c16a47603e9482.nc" --outfig=/data/jservon/climafcache/75/d24e74bf74bcda03f4c32291ea9d43fc3e186aa8b61a41dca55e64_27813.png --labels='"ccdo(space_average(ds('CMIP5%%tos%1950-2005%global%/bdd%CNRM-CM5%*%historical%r1i1p1%monthly%ocean%v20130101')),operator='yearmean')"' --variable=tos --colors="" --alphas="" --linestyles="" --min="" --max="" --lw="" --offset="-273.15" --scale="" --highlight_period="" --highlight_period_lw="" --xlabel="Calendar time" --ylabel="Temperature (degC)" --xlabel_fontsize="" --ylabel_fontsize="" --xlim="1951-01-01,2006-12-31" --ylim="17.7,18.8" --tick_size="" --text="" --text_fontsize="" --text_colors="" --text_verticalalignment="" --text_horizontalalignment="" --legend_colors="" --legend_labels="" --title="" --title_fontsize="" --left_string="Sea Surface Temperature" --right_string="model = CNRM-CM5" --center_string="" --left_string_fontsize="30" --right_string_fontsize="20" --center_string_fontsize="" --legend_loc="" --legend_xy_pos="" --legend_labels="" --legend_colors="" --legend_fontsize="" --legend_ncol="" --legend_lw="" --draw_legend="" --legend_frame="" --append_custom_legend_to_default="" --left_margin="" --right_margin="" --top_margin="" --bottom_margin="" --horizontal_lines_values="" --horizontal_lines_styles="" --horizontal_lines_lw="" --horizontal_lines_colors="" --vertical_lines_values="" --vertical_lines_styles="" --vertical_lines_lw="" --vertical_lines_colors="" --fig_size="" 

List of CliMAF objects

One object...

In [7]:
# -- Possibility to provide one, or more
# -- By default ts_plot uses the CRS of the CliMAF object for the legend
myplot = ts_plot( [ts_dat] )
iplot(myplot)
Out[7]:

... or several

In [8]:
# -- It is possible to provide more than one to plot multiple time series
# -- !!! can't provide twice the same object within the same list
myplot = ts_plot( [ts_dat, fadd(ts_dat, 0.1)] )
iplot(myplot)
Out[8]:

Python dictionary with explicit names for the legend

In [9]:
# -- It is possible to provide more than one to plot multiple time series
# -- Unlike with list, yoiu can provide the same object twice but with different names
myplot = ts_plot( dict(ts_dat=ts_dat, ts_dat01=fadd(ts_dat, 0.1) ) ) #ts_dat01=ts_dat
iplot(myplot)
Out[9]:

CliMAF ensemble

In [10]:
# -- Same principle as a python dictionary but with a specified order
myplot = ts_plot( cens( dict(ts_dat=ts_dat, ts_dat01=fadd(ts_dat, 0.1) ), order=['ts_dat','ts_dat01'] ) )
iplot(myplot)
Out[10]:

1.b: Control figure size and plot margins

We control the size of the figure and the X/Y ratio with fig_size.

By default, fig_size = '15*5', which means 15 inches in length and 5 in height.

Let's change it for '15*10'

In [11]:
myplot = ts_plot(ts_dat,
                 fig_size = '15*10',
                )
iplot(myplot)
Out[11]:

We control the width of the margins with (left,right,bottom,top)_margin.

The value is the position of the axis within the coordinates of the frame, with:

for left_margin and right_margin:

  • left border: 0
  • right border: 1

for bottom_margin and top_margin:

  • bottom border: 0
  • top border: 1
In [12]:
myplot = ts_plot(ts_dat,
                 fig_size = '15*10',
                 left_margin = 0.1,
                 right_margin = 1,
                 bottom_margin = 0.01,
                 top_margin = 0.8
                )
iplot(myplot)
Out[12]:

2. Customize the plot

2.a: edit the titles, labels and axis

  • offset, scale the value of the data
  • x and y limits of the plot
  • x and y axis labels
  • titles
In [13]:
myplot = ts_plot(ts_dat,
                     offset = -273.15,
                     # - X and Y limits
                     xlim = ['1951-01-01','2006-12-31'],
                     ylim = [17.7,18.8],
                     # -- X and Y labels
                     xlabel = 'Calendar time',
                     ylabel = 'Temperature (degC)',
                     # -- Title strings
                     left_string = 'Sea Surface Temperature',
                     right_string = 'model = '+dat.model,
                     left_string_fontsize = 30,
                     right_string_fontsize = 20
                     #center_string = '',
                     #center_string_fontsize: Center string size
                )
iplot(myplot)
Out[13]:

2.b: lines colors, thickness, styles and transparency

In [14]:
myplot = ts_plot(dict(ts_dat=ts_dat,
                      ts_dat01=fadd(ts_dat, 0.1),
                      ts_dat02=fadd(ts_dat, 0.2) ),
                 offset = -273.15,
                 xlim = ['1951-01-01','2006-12-31'],
                 ylim = [17.7,18.8],
                 xlabel = 'Calendar time',
                 ylabel = 'Temperature (degC)',
                 left_string = 'Sea Surface Temperature',
                 right_string = 'model = '+dat.model,
                 left_string_fontsize = 30,
                 right_string_fontsize = 20,
                     # -- Colors (use python colors: https://python-graph-gallery.com/python-colors/)
                     colors = ['red','blue','green'],
                     # -- Line widths: default is 1
                     lw = [5,2,5],
                     # -- Line styles: have a look at this page to see the values you can use to specify the line styles:
                     #    https://matplotlib.org/3.1.0/gallery/lines_bars_and_markers/linestyles.html
                     #    Note: if you want to use a tuple, like (0,(3,5,1,5)), you should use a string
                     #    with values separated with dash, like '0-3-5-1-5'
                     linestyles=['solid','dashed','0-3-5-1-5'], #,
                     # -- Alphas: line opacity
                     #      -> 0 transparent
                     #      -> 1 opac
                     alphas = [0.2, 1, 1],
                )
iplot(myplot)
Out[14]:

2.c: highlight a period with a thicker line

In [15]:
myplot = ts_plot(ts_dat,
                 offset = -273.15,
                 xlim = ['1951-01-01','2006-12-31'],
                 ylim = [17.7,18.8],
                 xlabel = 'Calendar time',
                 ylabel = 'Temperature (degC)',
                 left_string = 'Sea Surface Temperature',
                 right_string = 'model = '+dat.model,
                 left_string_fontsize = 30,
                 right_string_fontsize = 20,
                 #center_string = '',
                 #center_string_fontsize: Center string size
                 colors = 'red',
                 lw = 2,
                     highlight_period = '1980-2000',
                     highlight_period_lw = 8,
                )
iplot(myplot)
Out[15]: