Non-thermal pCO2 by area¶

Author: Kai Yang

Manuscript: Global trends in ocean fronts: impacts on air-sea CO2 flux and chlorophyll concentrations

Creation date: 2024-Aug-19

Latest update: 2025-Jun-03

This Jupyter notebook produces Supplementary Fig. 2 of the manuscript.

In [1]:
# Import libraries
import xarray as xr
import cartopy.crs as ccrs
import pandas as pd
import pylab as plt
import numpy as np
# Inline plotting
# %matplotlib inline
import matplotlib.font_manager as font_manager
from matplotlib import ticker
from matplotlib.lines import Line2D
import geopandas as gpd
/Users/kyang7/anaconda3/lib/python3.11/site-packages/pandas/core/arrays/masked.py:60: UserWarning: Pandas requires version '1.3.6' or newer of 'bottleneck' (version '1.3.5' currently installed).
  from pandas.core import (
In [2]:
from utils import area,ccrs_land,add_patches
In [3]:
# read non-thermal pCO2 climatology
pco2_dataset = xr.open_dataset('../datasets/maps/pco2_t_nt_2022.nc',chunks={'lat':10,'lon':10})
pco2_nt_2022 = pco2_dataset.pco2_nt_2022
In [4]:
# read frontal areas shapefiles
keyF = gpd.read_file(r'../datasets/shapefiles/cumulativeMask.shp')
decF = gpd.read_file(r'../datasets/shapefiles/overlapMask_decline.shp')
intF = gpd.read_file(r'../datasets/shapefiles/overlapMask_intensify.shp')
In [5]:
# read mean non-thermal pco2 values in areas
values_pco2 = xr.open_dataset('../datasets/timeseries/pCO2_masked_ts.nc')
pco2_key = values_pco2.pCO2_key
pco2_intens = values_pco2.pCO2_int
pco2_declin = values_pco2.pCO2_dec
pco2_remain = values_pco2.pCO2_rem
pco2_glb = values_pco2.pCO2_global

pco2_combined=np.array([pco2_glb.mean(), pco2_key.mean(), pco2_intens.mean(), pco2_declin.mean(), pco2_remain.mean()])
In [6]:
fig = plt.figure(figsize=(30, 15),dpi=600)

plt.rcParams['figure.figsize'] = [30, 15]
#################################################################################################################################################
# Panel a
ax1 = plt.axes([0.2, 0.267, 0.19, 0.168],projection = ccrs.Robinson(central_longitude=180))

# mapping
im1 = pco2_nt_2022.plot(ax=ax1, transform = ccrs.PlateCarree(), add_colorbar=False,
                       cmap = 'rainbow', rasterized=True, vmin = 300, vmax = 450) 
# frontal areas
keyF.plot(transform=ccrs.PlateCarree(),edgecolor='k', facecolor="None", linewidth=1.5, linestyle = "-", alpha=1, ax = ax1)
decF.plot(transform=ccrs.PlateCarree(),edgecolor='#0787c3', facecolor="None", linewidth=1.5, linestyle = "-", alpha=1, ax = ax1)
intF.plot(transform=ccrs.PlateCarree(),edgecolor='#ec3232', facecolor="None", linewidth=1.5, linestyle = "-", alpha=1, ax = ax1)

plt.plot([0, 360], [60.1, 60.1],
         color='black', linewidth=1, linestyle='--', markersize=3,
         # Be explicit about which transform you want:
         transform = ccrs.PlateCarree())
plt.plot([0, 360], [-60.1, -60.1],
         color='black', linewidth=1, linestyle='--', markersize=3,
         # Be explicit about which transform you want:
         transform = ccrs.PlateCarree())

# map settings
ax1.set_extent([0.1,359.99,-85, 85], crs=ccrs.PlateCarree())
ax1.add_feature(ccrs_land)
add_patches(ax1)
ax1.set_title("a  Non-thermal pCO$_2$ ",fontname = 'Arial', fontsize=12,loc = 'left', fontweight = 'bold')
gl = ax1.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                  linewidth=0.5, color='gray', alpha=0.0, linestyle='--')
gl.xlabels_top = False
gl.ylabels_left = True
gl.xlabels_bottom = True
gl.ylabels_right = False
gl.xlabel_style = {'size': 12, 'color': 'k','name':'Arial'}
gl.ylabel_style = {'size': 12, 'color': 'k','name':'Arial'}

#legend
colors1 = ['k', '#ec3232', '#0787c3']
lines = [Line2D([0], [0], color=c, linewidth=1.5, linestyle='-') for c in colors1]
labels = ['Key', 'Intensifying', 'Declining']
font = font_manager.FontProperties(family='Arial',size = 8)
plt.legend(lines, labels,loc='lower center', ncols=3, frameon=True,prop=font)

# colorbar
cbar_ax = fig.add_axes([0.19, 0.28, 0.005, 0.15])
cbar=fig.colorbar(im1, cax=cbar_ax,orientation='vertical',extend='both')
cbar.set_label('µatm', rotation = 90,fontname = 'Arial', fontsize=12, labelpad=-50)
cbar.ax.tick_params(labelsize=10)
cbar.ax.yaxis.tick_left()
# #################################################################################################################################################
# Panel b
ax2 = plt.axes([0.39, 0.267, 0.1, 0.167])

areas = ['Global','Key', 'Intensifying', 'Declining', 'Remaining']
bar_colors = ['#a6519e','k', '#ec3232', '#0787c3', 'darkgrey']

pco2 = pco2_combined

# bar plot
rects=ax2.bar(areas, pco2, label=areas, color=bar_colors)
loc1 = [0,1,2,3,4]

# Make some labels.
labels = [f'label{i}' for i in range(len(rects))]
which = [0,1,2,3,4]
for index, rect in enumerate(rects):
    if index in which:
            ax2.text(loc1[index],rect.get_y() + rect.get_height()+0.2,'{:,.1f}'.format(pco2[index]),
                ha='center', va='bottom', fontname = 'Arial', fontsize = 11)

# plot settings
ax2.set_ylabel('µatm', fontname = 'Arial', fontsize=12)
ax2.set_title('b  Average non-thermal pCO$_2$ ', loc = 'left', fontname = 'Arial', fontsize = 12, fontweight = 'bold')
ax2.yaxis.grid(True, linestyle='--', which='major',
                   color='grey', alpha=.25)
ax2.axhline(0, color='grey')  # median position
ax2.set_yticks([350,360, 370,380,390,400,410,420])
ax2.set_yticklabels([350,360, 370,380,390,400,410,420],fontname = 'Arial',fontsize = 10)
ax2.set_ylim(350, 400)
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(False) 
formatter.set_powerlimits((-1,1)) 
ax2.yaxis.set_major_formatter(formatter)
ax2.yaxis.tick_right()
ax2.yaxis.set_label_position("right")
ax2.set_xticklabels(areas, fontname = 'Arial', fontsize = 10,rotation = 30)
# #################################################################################################################################################
plt.savefig('../JPEG/FigS2_pCO2_by_areas_2022.jpeg',dpi=600,bbox_inches='tight')
plt.show()
/Users/kyang7/anaconda3/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:451: UserWarning: The .xlabels_top attribute is deprecated. Please use .top_labels to toggle visibility instead.
  warnings.warn('The .xlabels_top attribute is deprecated. Please '
/Users/kyang7/anaconda3/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:475: UserWarning: The .ylabels_left attribute is deprecated. Please use .left_labels to toggle visibility instead.
  warnings.warn('The .ylabels_left attribute is deprecated. Please '
/Users/kyang7/anaconda3/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:463: UserWarning: The .xlabels_bottom attribute is deprecated. Please use .bottom_labels to toggle visibility instead.
  warnings.warn('The .xlabels_bottom attribute is deprecated. Please '
/Users/kyang7/anaconda3/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:487: UserWarning: The .ylabels_right attribute is deprecated. Please use .right_labels to toggle visibility instead.
  warnings.warn('The .ylabels_right attribute is deprecated. Please '
/var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72990/1448419244.py:88: UserWarning: FixedFormatter should only be used together with FixedLocator
  ax2.set_xticklabels(areas, fontname = 'Arial', fontsize = 10,rotation = 30)

Supplementary Figure 2 Spatial distribution of surface partial pressure of CO2 (pCO2) in seawater. Panel a: Estimated surface non-thermal pCO2 for 2022 within key frontal areas (black contours), intensifying frontal areas (red contours), and declining frontal areas (blue contours). Panel b: Estimated average non-thermal pCO2 for 2022 within frontal areas. Non-thermal pCO2 represents the seawater partial pressure of CO2 corrected for temperature effects, isolating the influence of biological activity, mixing, and other non-thermal processes. Lower values suggest enhanced biological CO2 uptake or reduced upwelling of CO2-rich waters, while higher values indicate stronger non-thermal CO2 sources.

:)