Carbon.py

by Pearse Buchanan

 

# -*- coding: utf-8 -*-
"""
Created on Fri May 05 08:04:53 2017

@author: pearseb
"""

#%% import neccesary packages for plotting

import numpy as np
import matplotlib.pyplot as plt

 

# these modules allow good control on asymetric multipanel plots
from matplotlib import gridspec 
from mpl_toolkits.axes_grid1 import make_axes_locatable

#%% generate colour scheme 

tableau20 = [(31, 119, 180), (174, 199, 232), (255, 127, 14), (255, 187, 120),
             (44, 160, 44), (152, 223, 138), (214, 39, 40), (255, 152, 150),
             (148, 103, 189), (197, 176, 213), (140, 86, 75), (196, 156, 148),
             (227, 119, 194), (247, 182, 210), (127, 127, 127), (199, 199, 199),
             (188, 189, 34), (219, 219, 141), (23, 190, 207), (158, 218, 229)]
 

# Scale the RGB values to the [0, 1] range, which is the format matplotlib accepts.
for i in range(len(tableau20)):
    r, g, b = tableau20[i]
    tableau20[i] = (r / 255., g / 255., b / 255.)
    

 

#%% Creating Panel (a)
# In this panel I am plotting the rolling standard deviation about the mean for experiments using the same 6 models

# create the figure
fig = plt.figure(facecolor='w',figsize=(10,15))

# split the figure into 3 areas for subplots (3 rows by 1 column)
gs = gridspec.GridSpec(3,1)

# select the first panel (the top one)
ax1 = plt.subplot(gs[0])

# remove the top and right spines from the frame of the panel plot and make the ticks invisible in these spines
ax1.spines['top'].set_visible(False)
ax1.spines['right'].set_visible(False)
plt.tick_params(axis='both', which='both', top='off', right='off')

# make a horizontal line across the panel to represent the observational mean and add text
plt.plot((-90,90),(0,0),'k:',alpha=0.5)
plt.text(-88,0.05,'GLODAP', fontsize=10, family='serif')

# plot the rolling standard deviation about the multi-model mean with latitude for both experiments
plt.fill_between(lat,b_dic_obmean+b_dic_obstd, b_dic_obmean-b_dic_obstd, color='slategrey',alpha=0.2,zorder=0, label='Base')
plt.fill_between(lat,c_dic_obmean+c_dic_obstd, c_dic_obmean-c_dic_obstd, color='firebrick',alpha=0.2,zorder=0, label='COM')

# make the tick labels nice by manually defining their font, size and text for both axes
lats = ['80$^{\circ}$S', '60$^{\circ}$S', '40$^{\circ}$S', '20$^{\circ}$S', '0$^{\circ}$', \
        '20$^{\circ}$N', '40$^{\circ}$N', '60$^{\circ}$N', '80$^{\circ}$N']
plt.xticks(np.arange(-80,81,20),lats,fontsize=12,family='serif')
plt.yticks(np.arange(-10,11,5),np.arange(-10,11,5),fontsize=12,family='serif')

# set the y axis label
plt.ylabel('$\Delta$ DIC (Pg)', fontsize=14, family='serif')

# set the x and y range for the plot
plt.ylim(-14,14); plt.xlim(-90,90)

# add a legend with two columns, no frame, in the upper centre of the panel
plt.legend(loc='upper center', scatterpoints=1, ncol=2, frameon=False, fontsize=14, columnspacing=0.5, markerscale=4)

 

#%% Creating panel (b)

# select the second subspace (middle) for plotting
ax2 = plt.subplot(gs[1])

# remove the top and right spines from the frame of the panel plot and make the ticks invisible in these spines
ax2.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)
plt.tick_params(axis='both', which='both', top='off', right='off')

# make a horizontal line across the panel to represent the mulit-model mean and add text
plt.plot((-90,90),(np.ma.mean(c2p),np.ma.mean(c2p)),'k:',alpha=0.5)
plt.text(-88,np.ma.mean(c2p)+1,'mean = 111', fontsize=10, family='serif')

# plot the zonal average C:P ratio at the surface ocean for each model, giving each a label and a different colour according to the tableau20 scale defined above
plt.plot(lat, mk3l_c2p_rrdif_x + np.ma.mean(c2p), color=tableau20[0], zorder=1, label='Mk3L')
plt.plot(lat, gfdl_c2p_rrdif_x + np.ma.mean(c2p), color=tableau20[2], zorder=1, label='GFDL')
plt.plot(lat, ipsl_c2p_rrdif_x + np.ma.mean(c2p), color=tableau20[4], zorder=1, label='IPSL')
plt.plot(lat, hadgem_c2p_rrdif_x + np.ma.mean(c2p), color=tableau20[6], zorder=1, label='HadGEM')
plt.plot(lat, mpi_c2p_rrdif_x + np.ma.mean(c2p), color=tableau20[8], zorder=1, label='MPI')
plt.plot(lat, mri_c2p_rrdif_x + np.ma.mean(c2p), color=tableau20[10], zorder=1, label='MRI')    

# make the tick labels nice by manually defining their font, size and text for both axes
lats = ['80$^{\circ}$S', '60$^{\circ}$S', '40$^{\circ}$S', '20$^{\circ}$S', '0$^{\circ}$', \
        '20$^{\circ}$N', '40$^{\circ}$N', '60$^{\circ}$N', '80$^{\circ}$N']
plt.xticks(np.arange(-80,81,20),lats,fontsize=12,family='serif')
plt.yticks(np.arange(40,181,20),np.arange(40,181,20),fontsize=12,family='serif')

# set the y axis label
plt.ylabel('C:P$_{COM}$', fontsize=14, family='serif')

# set the x and y range for the plot
plt.ylim(40,180); plt.xlim(-90,90)

# add a legend with three columns, no frame, in the bottom right of the panel
plt.legend(loc='lower right', scatterpoints=1, ncol=3, frameon=False, fontsize=14, columnspacing=0.5, markerscale=4)

 

#%% Creating panels (c) and (d)

# select the third subspace (bottom) for plotting
ax3 = plt.subplot(gs[2])

# remove the top and right spines from the frame of the panel plot and make the ticks invisible in these spines
ax3.spines['top'].set_visible(False)
ax3.spines['right'].set_visible(False)
plt.tick_params(axis='both', which='both', top='off', right='off')

 

# define an index for selecting tableau20 colours in the following loop
cols = np.array([0,2,4,6,8,10])

# loop over six data points in both the cellsA and baseC arrays and make each have a different colour in the scatter plot
for n in np.arange(6):
 
# scatter plot with different colours
    plt.scatter(cellsA[n], baseC[n], color='slategrey', edgecolor=tableau20[cols[n]], marker='o', s=200, zorder=1, linewidth=4)

# setmark holds the model number from 1-6 depending on the iteration    
    setmark = '$'+str(n+1)+'$'
    print setmark
   
# put the number (setmark) in the middle of the scatter plot

    plt.scatter(cellsA[n], baseC[n], marker=setmark, s=75, zorder=2, color='k')    

 

# loop over six data points in both the cellsA and comC arrays and make each have a different colour in the scatter plot
for n in np.arange(6):

# scatter plot with different colours and a square marker this time    
    plt.scatter(cellsA[n], comC[n], color='slategrey', edgecolor=tableau20[cols[n]], marker='s', s=200, zorder=1, linewidth=4)

# connect the circles and squares with black straight lines that emphasise changes between experiments    
    plt.plot((cellsA[n], cellsA[n]), (baseC[n],comC[n]), '-k',zorder=0)

 

# fill in the mean and one standard deviation about the mean for each multi-model experiment
    # here, the mean of the baseC array is dashed horizontal black line

plt.plot((0.8,1.8),(np.mean(baseC),np.mean(baseC)),'k:',alpha=0.5)

    # here, the standard deviation of the baseC array is grey shaded, with a transparency of 80% (alpha=0.2)
plt.axhspan(np.mean(baseC)-np.std(baseC),np.mean(baseC)+np.std(baseC), color='slategrey', alpha=0.2,zorder=0)

# fill in the mean and one standard deviation about the mean for each multi-model experiment
    # here, the mean of the comC array is dashed horizontal red line

plt.plot((0.8,1.8),(np.mean(comC),np.mean(comC)),':', color='firebrick', alpha=0.5)

    # here, the standard deviation of the baseC array is pink shaded, with a transparency of 80% (alpha=0.2)
plt.axhspan(np.mean(comC)-np.std(comC),np.mean(comC)+np.std(comC), color='firebrick', alpha=0.2,zorder=0)

# make the tick labels nice by manually defining their font, size and text for both axes
plt.xticks(np.arange(0.8,1.8,0.1),np.arange(0.8,1.8,0.1),fontsize=12,family='serif')
plt.yticks(np.arange(33800,34601,200),np.arange(33800,34601,200),fontsize=12,family='serif')

# set the x and y axis labels with nice font
plt.xlabel('$\Omega_{Atl}$', fontsize=14, family='serif')
plt.ylabel('DIC (Pg)', fontsize=14, family='serif')

# set the x and y range for the plot
plt.ylim(33700,34600); plt.xlim(0.8,1.8)

# This command splits the current panel (c) into two, allowing for two subplots in the bottom third of the figure, (c) and (d)
divider = make_axes_locatable(ax3)

# we now call this new subplot by another name, and choose its location, 
# dimensions relative to the other plot, and how close it is to the other plot

ax3right = divider.append_axes('right', size="100%", pad=0.5)

 

# this time the plot is on the right, so we should remove the top and left spines from the frame and make the ticks invisible in these spines
ax3right.spines['top'].set_visible(False)
ax3right.spines['right'].set_visible(True)
ax3right.spines['left'].set_visible(False)
plt.tick_params(axis='both', which='both', top='off', right='on', labelright='on', left='off', labelleft='off')

 

# again, set the index array for selecting tableau20 colours
cols = np.array([0,2,4,6,8,10])

 

# loop over six data points in both the c2p_difs and comC-baseC arrays and make each have a different colour in the scatter plot
for n in np.arange(6):

# scatter plot with different colours
plt.scatter(c2p_difs[n]+106, comC[n]-baseC[n], color='slategrey', edgecolor=tableau20[cols[n]], marker='s', s=200, zorder=1, linewidth=4)
# setmark holds the model number from 1-6 depending on the iteration    
setmark = '$'+str(n+1)+'$'
print setmark
# put the number (setmark) in the middle of the scatter plot
plt.scatter(c2p_difs[n]+106, comC[n]-baseC[n], marker=setmark, s=75, zorder=2, color='k')    

 

# make the tick labels nice by manually defining their font, size and text for both axes
plt.xticks(np.arange(106,106+19,4),np.arange(106,106+19,4),fontsize=12,family='serif')
plt.yticks(np.arange(-400,-99,50),np.arange(-400,-99,50),fontsize=12,family='serif')

 

# set the x and y axis labels with nice font
plt.ylabel('$\Delta$ DIC$_{COM-Base}$ (Pg)', fontsize=14, family='serif')
plt.xlabel('C:P$_{COM}$', fontsize=14, family='serif')

 

# manually set the y axis label to be on the right side of the plot
ax3right.yaxis.set_label_position('right')

#%% finally, label all the panels and save the figure

ax1.text(0.025,0.925,'a)',fontsize=14,family='serif',transform=ax1.transAxes)
ax2.text(0.025,0.925,'b)',fontsize=14,family='serif',transform=ax2.transAxes)
ax3.text(0.025,0.925,'c)',fontsize=14,family='serif',transform=ax3.transAxes)
ax3right.text(0.025,0.925,'d)',fontsize=14,family='serif',transform=ax3right.transAxes)

fig.savefig('carbon.png',dpi=300,bbox_inches='tight')

 

UNSW logo ANU logo Monash logo UMelb logo UTAS logo