Author: Kai Yang
Manuscript: Global trends in ocean fronts: impacts on air-sea CO2 flux and chlorophyll concentrations
Creation date: 2024-May-21
Latest update: 2025-Jun-03
This Jupyter notebook produces Fig. 3 of the manuscript.
# Import libraries
import xarray as xr
import numpy as np
import pandas as pd
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
from matplotlib import ticker
/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 (
# Import plot utilities
from plot_utils_v2 import (significance_mk,plot_barhs,compute_trends)
import numpy as np
from netCDF4 import Dataset
import matplotlib.pyplot as plt
# Read the annual datasets (e.g., 'Ffreq_masked_ts.nc', 'CO2_masked_ts.nc', etc.)
def read_netcdf_file(file_name):
# Open the NetCDF file
with Dataset(file_name, 'r') as nc:
print(nc.variables.keys()) # Show available variables
# Read time or any other general information
if 'year' in nc.variables:
years = nc.variables['year'][:]
print(f"Years: {years}")
# Loop through the variables and regions
data = {}
for var_name in nc.variables:
if var_name != 'year': # Skip the year variable
data[var_name] = nc.variables[var_name][:]
print(f"{var_name} shape: {data[var_name].shape}")
return data
# Example: Read the Ffreq data file
file_name = '../datasets/timeseries/Ffreq_masked_ts.nc'
Ffreq_data = read_netcdf_file(file_name)
key_Ffreq = Ffreq_data['Ffreq_key']
int_Ffreq = Ffreq_data['Ffreq_int']
dec_Ffreq = Ffreq_data['Ffreq_dec']
rem_Ffreq = Ffreq_data['Ffreq_rem']
glb_Ffreq = Ffreq_data['Ffreq_global']
file_name = '../datasets/timeseries/Fdens_masked_ts.nc'
Fdens_data = read_netcdf_file(file_name)
key_Fdens = Fdens_data['Fdens_key']
int_Fdens = Fdens_data['Fdens_int']
dec_Fdens = Fdens_data['Fdens_dec']
rem_Fdens = Fdens_data['Fdens_rem']
glb_Fdens = Fdens_data['Fdens_global']
file_name = '../datasets/timeseries/Fstre_masked_ts.nc'
Fstre_data = read_netcdf_file(file_name)
key_Fstre = Fstre_data['Fstre_key']
int_Fstre = Fstre_data['Fstre_int']
dec_Fstre = Fstre_data['Fstre_dec']
rem_Fstre = Fstre_data['Fstre_rem']
glb_Fstre = Fstre_data['Fstre_global']
# file_name = '../datasets/timeseries/CO2_masked_ts.nc'
# CO2_data = read_netcdf_file(file_name)
# key_CO2 = CO2_data['CO2_key']
dict_keys(['year', 'Ffreq_key', 'Ffreq_dec', 'Ffreq_int', 'Ffreq_rem', 'Ffreq_global']) Years: [2003. 2004. 2005. 2006. 2007. 2008. 2009. 2010. 2011. 2012. 2013. 2014. 2015. 2016. 2017. 2018. 2019. 2020. 2021. 2022. 2023.] Ffreq_key shape: (21,) Ffreq_dec shape: (21,) Ffreq_int shape: (21,) Ffreq_rem shape: (21,) Ffreq_global shape: (21,) dict_keys(['year', 'Fdens_key', 'Fdens_dec', 'Fdens_int', 'Fdens_rem', 'Fdens_global']) Years: [2003. 2004. 2005. 2006. 2007. 2008. 2009. 2010. 2011. 2012. 2013. 2014. 2015. 2016. 2017. 2018. 2019. 2020. 2021. 2022. 2023.] Fdens_key shape: (21,) Fdens_dec shape: (21,) Fdens_int shape: (21,) Fdens_rem shape: (21,) Fdens_global shape: (21,) dict_keys(['year', 'Fstre_key', 'Fstre_dec', 'Fstre_int', 'Fstre_rem', 'Fstre_global']) Years: [2003. 2004. 2005. 2006. 2007. 2008. 2009. 2010. 2011. 2012. 2013. 2014. 2015. 2016. 2017. 2018. 2019. 2020. 2021. 2022. 2023.] Fstre_key shape: (21,) Fstre_dec shape: (21,) Fstre_int shape: (21,) Fstre_rem shape: (21,) Fstre_global shape: (21,)
## Frontal frequency time series
# MODIS
trend_times = pd.date_range(start='1/06/2003', end='1/06/2024',freq='12M')
MFfreq1 = key_Ffreq
MFfreq2 = int_Ffreq
MFfreq3 = dec_Ffreq
MFfreq4 = rem_Ffreq
MFfreq5 = glb_Ffreq
MFfreq1_da = xr.DataArray(data=MFfreq1,
coords=dict(time=trend_times))
MFfreq2_da = xr.DataArray(data=MFfreq2,
coords=dict(time=trend_times))
MFfreq3_da = xr.DataArray(data=MFfreq3,
coords=dict(time=trend_times))
MFfreq4_da = xr.DataArray(data=MFfreq4,
coords=dict(time=trend_times))
MFfreq5_da = xr.DataArray(data=MFfreq5,
coords=dict(time=trend_times))
/var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/40333117.py:4: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead. trend_times = pd.date_range(start='1/06/2003', end='1/06/2024',freq='12M')
## Frontal density time series
# MODIS
trend_times = pd.date_range(start='1/06/2003', end='1/06/2024',freq='12M')
MFdens1 = key_Fdens
MFdens2 = int_Fdens
MFdens3 = dec_Fdens
MFdens4 = rem_Fdens
MFdens5 = glb_Fdens
MFdens1_da = xr.DataArray(data=MFdens1,
coords=dict(time=trend_times))
MFdens2_da = xr.DataArray(data=MFdens2,
coords=dict(time=trend_times))
MFdens3_da = xr.DataArray(data=MFdens3,
coords=dict(time=trend_times))
MFdens4_da = xr.DataArray(data=MFdens4,
coords=dict(time=trend_times))
MFdens5_da = xr.DataArray(data=MFdens5,
coords=dict(time=trend_times))
/var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/2382555575.py:4: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead. trend_times = pd.date_range(start='1/06/2003', end='1/06/2024',freq='12M')
## Frontal strength time series
# MODIS
trend_times = pd.date_range(start='1/06/2003', end='1/06/2024',freq='12M')
MFstre1 = key_Fstre
MFstre2 = int_Fstre
MFstre3 = dec_Fstre
MFstre4 = rem_Fstre
MFstre5 = glb_Fstre
MFstre1_da = xr.DataArray(data=MFstre1,
coords=dict(time=trend_times))
MFstre2_da = xr.DataArray(data=MFstre2,
coords=dict(time=trend_times))
MFstre3_da = xr.DataArray(data=MFstre3,
coords=dict(time=trend_times))
MFstre4_da = xr.DataArray(data=MFstre4,
coords=dict(time=trend_times))
MFstre5_da = xr.DataArray(data=MFstre5,
coords=dict(time=trend_times))
/var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/1330918028.py:4: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead. trend_times = pd.date_range(start='1/06/2003', end='1/06/2024',freq='12M')
## compute trends
# MODIS
slope_MFfreq1, intercept_MFfreq1 = compute_trends(MFfreq1)
slope_MFfreq2, intercept_MFfreq2 = compute_trends(MFfreq2)
slope_MFfreq3, intercept_MFfreq3 = compute_trends(MFfreq3)
slope_MFfreq4, intercept_MFfreq4 = compute_trends(MFfreq4)
slope_MFfreq5, intercept_MFfreq5 = compute_trends(MFfreq5)
slope_MFdens1, intercept_MFdens1 = compute_trends(MFdens1)
slope_MFdens2, intercept_MFdens2 = compute_trends(MFdens2)
slope_MFdens3, intercept_MFdens3 = compute_trends(MFdens3)
slope_MFdens4, intercept_MFdens4 = compute_trends(MFdens4)
slope_MFdens5, intercept_MFdens5 = compute_trends(MFdens5)
slope_MFstre1, intercept_MFstre1 = compute_trends(MFstre1)
slope_MFstre2, intercept_MFstre2 = compute_trends(MFstre2)
slope_MFstre3, intercept_MFstre3 = compute_trends(MFstre3)
slope_MFstre4, intercept_MFstre4 = compute_trends(MFstre4)
slope_MFstre5, intercept_MFstre5 = compute_trends(MFstre5)
fig = plt.figure(figsize=(10,6),dpi=400)
ax1 = fig.add_subplot(231)
ax2 = fig.add_subplot(232)
ax3 = fig.add_subplot(233)
ax4 = fig.add_subplot(234)
ax5 = fig.add_subplot(235)
ax6 = fig.add_subplot(236)
names = ['', 'Remaining','Declining','Intensifying','Key','Global Ocean']
########################################################################################################################
# Panel a
# calculate means
MFdens1_mean = MFdens1.mean()
MFdens2_mean = MFdens2.mean()
MFdens3_mean = MFdens3.mean()
MFdens4_mean = MFdens4.mean()
MFdens5_mean = MFdens5.mean()
# EFdens1_mean = EFdens1.mean()
# EFdens3_mean = EFdens3.mean()
MFdens=np.array([MFdens4_mean,MFdens3_mean,MFdens2_mean,MFdens1_mean,MFdens5_mean])
# bar plot
rects = ax1.barh([1,2,3,4,5],MFdens,color = '#830783',alpha = 0.5,height = 0.3)
# rects1 = ax1.barh([1.8],EFdens3_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# rects2 = ax1.barh([3.8],EFdens1_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# bar labels
ax1.bar_label(rects,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#830783')
# ax1.bar_label(rects1,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# ax1.bar_label(rects2,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# plot settings
ax1.xaxis.set_major_locator(MultipleLocator(10))
ax1.xaxis.set_minor_locator(MultipleLocator(5))
ax1.yaxis.set_major_locator(MultipleLocator(1))
ax1.set_yticklabels(names,fontname = 'Arial', fontsize = 12)
ax1.set_xticks([0,10,20,30])
ax1.set_xticklabels([0,10,20,30],fontname = 'Arial', fontsize = 12)
ax1.set_title(r"a",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax1.set_xlabel("%",fontname = 'Arial', fontsize = 12)
ax1.set_xlim(0,30)
ax1.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel b
# calculate means
MFfreq1_mean = MFfreq1.mean()
MFfreq2_mean = MFfreq2.mean()
MFfreq3_mean = MFfreq3.mean()
MFfreq4_mean = MFfreq4.mean()
MFfreq5_mean = MFfreq5.mean()
# EFfreq1_mean = EFfreq1.mean()
# EFfreq3_mean = EFfreq3.mean()
MFfreq=np.array([MFfreq4_mean,MFfreq3_mean,MFfreq2_mean,MFfreq1_mean,MFfreq5_mean])
# bar plot
rects = ax2.barh([1,2,3,4,5],MFfreq,color = '#830783',alpha = 0.5,height = 0.3)
# rects1 = ax2.barh([1.8],EFfreq3_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# rects2 = ax2.barh([3.8],EFfreq1_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# bar labels
ax2.bar_label(rects,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#830783')
# ax2.bar_label(rects1,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# ax2.bar_label(rects2,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# plot settings
ax2.xaxis.set_major_locator(MultipleLocator(10))
ax2.xaxis.set_minor_locator(MultipleLocator(5))
ax2.yaxis.set_major_locator(MultipleLocator(1))
ax2.set_yticklabels([],rotation=90, ha="center",va='top',fontname = 'Arial', fontsize = 15)
ax2.set_xticks([0,10,20,30])
ax2.set_xticklabels([0,10,20,30],fontname = 'Arial', fontsize = 12)
ax2.set_title(r"b",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax2.set_xlabel("%",fontname = 'Arial', fontsize = 12)
ax2.set_xlim(0,30)
ax2.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel c
# calculate means
MFstre1_mean = MFstre1.mean()
MFstre2_mean = MFstre2.mean()
MFstre3_mean = MFstre3.mean()
MFstre4_mean = MFstre4.mean()
MFstre5_mean = MFstre5.mean()
# EFstre1_mean = EFstre1.mean()
# EFstre3_mean = EFstre3.mean()
MFstre=np.array([MFstre4_mean,MFstre3_mean,MFstre2_mean,MFstre1_mean,MFstre5_mean])*100
# bar plot
rects = ax3.barh([1,2,3,4,5],MFstre,color = '#830783',alpha = 0.5,height = 0.3)
# rects1 = ax3.barh([1.8],EFstre3_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# rects2 = ax3.barh([3.8],EFstre1_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# bar labels
ax3.bar_label(rects,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#830783')
# ax3.bar_label(rects1,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# ax3.bar_label(rects2,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# plot settings
ax3.xaxis.set_major_locator(MultipleLocator(2))
ax3.xaxis.set_minor_locator(MultipleLocator(1))
ax3.yaxis.set_major_locator(MultipleLocator(1))
ax3.set_yticklabels([], rotation=90,ha="center",va='top',fontname = 'Arial', fontsize = 12)
ax3.set_xticks([2,4,6,8])
ax3.set_xticklabels([2,4,6,8],fontname = 'Arial', fontsize = 12)
ax3.set_title(r"c",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax3.set_xlabel(" $\u00b0$C km$^{-1}$",fontname = 'Arial', fontsize = 12)
ax3.set_xlim(2,9)
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(False)
formatter.set_powerlimits((-1,1))
ax3.xaxis.set_major_formatter(formatter)
ax3.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel d
pos = ax4.get_position()
new_pos = [pos.x0, pos.y0-0.07, pos.width, pos.height]
ax4.set_position(new_pos)
loc1 = [1,2,3,4,5]
MFdens_slopes=np.array([slope_MFdens4,slope_MFdens3, slope_MFdens2, slope_MFdens1, slope_MFdens5])*10 # decadal trend
# bar plot
rects = ax4.barh([1,2,3,4,5],MFdens_slopes,color = '#830783',alpha = 0.5,height = 0.3)
# rects1 = ax4.barh([1.8],slope_EFdens3*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
# rects2 = ax4.barh([3.8],slope_EFdens1*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
# Make some labels.
labels = [f'label{i}' for i in range(len(rects))]
which = [1,2,3]
for index, rect in enumerate(rects):
if index in which:
if MFdens_slopes[index]<0:
ax4.text(rect.get_x() + rect.get_width()-1.5,loc1[index]-0.15,'{:,.2f}'.format(MFdens_slopes[index]),
ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
else:
ax4.text(rect.get_x() + rect.get_width()+1.5,loc1[index]-0.15,'+{:,.2f}'.format(MFdens_slopes[index]),
ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
# ax4.text(-3.2, 1.3,'{:,.2f}'.format(slope_EFdens3*10*365),
# ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# ax4.text(-2.4, 4,'{:,.2f}'.format(slope_EFdens1*10*365),
# ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# calculate trend significance and plot errorbar
integrated_timeseries = [MFdens4_da,MFdens3_da, MFdens2_da, MFdens1_da, MFdens5_da]
integrated_timeseries_dataarray = xr.concat(integrated_timeseries, dim='x')
hypothesis,n_effective = significance_mk(integrated_timeseries_dataarray)
dynamical_region_std=np.std(integrated_timeseries,axis=1)
dynamical_region_err=1.96*(dynamical_region_std/np.sqrt(n_effective))
for ii in range(1,6):
plot_barhs(ax4,ii,MFdens_slopes[ii-1],dynamical_region_err[ii-1],width=0.05,linestyle='-',color='black',linewidth=1)
# err_Fdens_extra = np.array([0.41949977, 0.32450672])
# plot_barhs(ax4,1.8,slope_EFdens3*10*365,err_Fdens_extra[1],width=0.05,linestyle='-',color='black',linewidth=1)
# plot_barhs(ax4,3.8,slope_EFdens1*10*365,err_Fdens_extra[0],width=0.05,linestyle='-',color='black',linewidth=1)
# plot settings
ax4.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=12)
ax4.xaxis.set_major_locator(MultipleLocator(3))
ax4.xaxis.set_minor_locator(MultipleLocator(1.5))
ax4.set_yticklabels(names,fontname = 'Arial', fontsize = 12)
ax4.set_title(r"d",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(True)
formatter.set_powerlimits((-1,1))
ax4.xaxis.set_major_formatter(formatter)
ax4.set_xlim(-6,6)
ax4.set_xlabel('% decade$^{-1}$',fontname = 'Arial', fontsize=12)
ax4.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
print(hypothesis)
########################################################################################################################
# Panel e
pos = ax5.get_position()
new_pos = [pos.x0, pos.y0-0.07, pos.width, pos.height]
ax5.set_position(new_pos)
MFfreq_slopes=np.array([slope_MFfreq4,slope_MFfreq3, slope_MFfreq2, slope_MFfreq1, slope_MFfreq5])*10 # decadal trend
# bar plot
rects = ax5.barh([1,2,3,4,5],MFfreq_slopes,color = '#830783',alpha = 0.5,height = 0.3)
# rects1 = ax5.barh([1.8],slope_EFfreq3*10*12,color = '#0e8585',height = 0.3, alpha = 0.3)
# rects2 = ax5.barh([3.8],slope_EFfreq1*10*12,color = '#0e8585',height = 0.3, alpha = 0.3)
# Make some labels.
labels = [f'label{i}' for i in range(len(rects))]
which = [1,2,3]
for index, rect in enumerate(rects):
if index in which:
if MFfreq_slopes[index]<0:
ax5.text(rect.get_x() + rect.get_width()-1.5,loc1[index]-0.15,'{:,.2f}'.format(MFfreq_slopes[index]),
ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
else:
ax5.text(rect.get_x() + rect.get_width()+1.5,loc1[index]-0.15,'+{:,.2f}'.format(MFfreq_slopes[index]),
ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
# ax5.text(-5, 1.3,'{:,.2f}'.format(slope_EFfreq3*10*12),
# ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# ax5.text(-3, 4,'{:,.2f}'.format(slope_EFfreq1*10*12),
# ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# calculate trend significance and plot errorbar
integrated_timeseries = [MFfreq4_da,MFfreq3_da, MFfreq2_da, MFfreq1_da, MFfreq5_da]
integrated_timeseries_dataarray = xr.concat(integrated_timeseries, dim='x')
hypothesis,n_effective = significance_mk(integrated_timeseries_dataarray)
dynamical_region_std=np.std(integrated_timeseries,axis=1)
dynamical_region_err=1.96*(dynamical_region_std/np.sqrt(n_effective))
for ii in range(1,6):
plot_barhs(ax5,ii,MFfreq_slopes[ii-1],dynamical_region_err[ii-1],width=0.05,linestyle='-',color='black',linewidth=1)
err_Ffreq_extra = np.array([0.49811791, 0.34789087])
# plot_barhs(ax5,1.8,slope_EFfreq3*10*12,err_Ffreq_extra[1],width=0.05,linestyle='-',color='black',linewidth=1)
# plot_barhs(ax5,3.8,slope_EFfreq1*10*12,err_Ffreq_extra[0],width=0.05,linestyle='-',color='black',linewidth=1)
# plot settings
ax5.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=12)
ax5.xaxis.set_major_locator(MultipleLocator(3))
ax5.xaxis.set_minor_locator(MultipleLocator(1.5))
ax5.set_yticklabels([],rotation=90, ha="center",va='top',fontname = 'Arial', fontsize=12)
ax5.set_title(r"e",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax5.set_xlim(-6,6)
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(True)
formatter.set_powerlimits((-1,1))
ax5.xaxis.set_major_formatter(formatter)
ax5.set_xlabel('% decade$^{-1}$',fontname = 'Arial', fontsize=12)
ax5.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
print(hypothesis)
########################################################################################################################
# Panel f
pos = ax6.get_position()
new_pos = [pos.x0, pos.y0-0.07, pos.width, pos.height]
ax6.set_position(new_pos)
MFstre_slopes=np.array([slope_MFstre4,slope_MFstre3, slope_MFstre2, slope_MFstre1, slope_MFstre5])*10*100 # decadal trend
# bar plot
rects = ax6.barh([1,2,3,4,5],MFstre_slopes,color = '#830783',alpha = 0.5,height = 0.3)
# rects1 = ax6.barh([1.8],slope_EFstre3*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
# rects2 = ax6.barh([3.8],slope_EFstre1*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
# Make some labels.
labels = [f'label{i}' for i in range(len(rects))]
which = [0,1,2,3]
for index, rect in enumerate(rects):
if index in which:
if MFstre_slopes[index]<0:
ax6.text(rect.get_x() + rect.get_width()-0.25,loc1[index]-0.15,'{:,.2f}'.format(MFstre_slopes[index]),
ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
else:
ax6.text(rect.get_x() + rect.get_width()+0.25,loc1[index]-0.15,'+{:,.2f}'.format(MFstre_slopes[index]),
ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
# ax6.text(-0.25, 1.3,'{:,.2f}'.format(slope_EFstre3*10*365),
# ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# ax6.text(-0.2, 4,'{:,.2f}'.format(slope_EFstre1*10*365),
# ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# calculate trend significance and plot errorbar
integrated_timeseries = [MFstre4_da,MFstre3_da, MFstre2_da, MFstre1_da, MFstre5_da]
integrated_timeseries_dataarray = xr.concat(integrated_timeseries, dim='x')
hypothesis,n_effective = significance_mk(integrated_timeseries_dataarray)
dynamical_region_std=np.std(integrated_timeseries,axis=1)
dynamical_region_err=1.96*(dynamical_region_std/np.sqrt(n_effective))
for ii in range(1,6):
plot_barhs(ax6,ii,MFstre_slopes[ii-1],dynamical_region_err[ii-1],width=0.05,linestyle='-',color='black',linewidth=1)
# err_Fstre_extra = np.array([0.00033134, 0.00023301])
# plot_barhs(ax6,1.8,slope_EFstre3*10*365,err_Fstre_extra[1]*100,width=0.05,linestyle='-',color='black',linewidth=1)
# plot_barhs(ax6,3.8,slope_EFstre1*10*365,err_Fstre_extra[0]*100,width=0.05,linestyle='-',color='black',linewidth=1)
# plot settings
ax6.set_xticklabels([-2,-1, 0, 1, 2],fontname = 'Arial', fontsize=12)
ax6.xaxis.set_major_locator(MultipleLocator(0.5))
ax6.xaxis.set_minor_locator(MultipleLocator(1))
ax6.set_yticklabels([], rotation=90,ha="center",va='top',fontname = 'Arial', fontsize = 12)
ax6.set_title(r"f",fontname = 'Arial', fontsize=15,fontweight = 'bold',loc = 'left')
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(False)
formatter.set_powerlimits((-1,1))
ax6.xaxis.set_major_formatter(formatter)
ax6.set_xlim(-1,1)
ax6.set_xlabel('$\u00b0$C km$^{-1}$ decade$^{-1}$',fontname = 'Arial', fontsize=12)
ax6.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
print(hypothesis)
########################################################################################################################
# Add some labels
ax1.text(-22,2.5,'Mean', fontname = 'Arial', fontsize = 15, fontweight = 'bold',rotation = 90)
ax1.text(-22,-4.2,'Trend', fontname = 'Arial', fontsize = 15, fontweight = 'bold',rotation = 90)
ax1.text(4, 6.3,'Frontal density', fontname = 'Arial', fontsize = 15,fontweight = 'bold')
ax2.text(4, 6.3,'Frontal frequency', fontname = 'Arial', fontsize = 15,fontweight = 'bold')
ax3.text(2.7, 6.3,'Frontal strength', fontname = 'Arial', fontsize = 15,fontweight = 'bold')
ax6.text(0.5, 5.5,'×10$^{-2}$', fontname = 'Arial', fontsize = 15)
ax3.text(7.2, 5.5,'×10$^{-2}$', fontname = 'Arial', fontsize = 15)
########################################################################################################################
plt.savefig('../JPEG/Fig3_frontal_metrics_by_area_weighted.jpeg',dpi=400,bbox_inches='tight')
/var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/226777559.py:44: UserWarning: FixedFormatter should only be used together with FixedLocator ax1.set_yticklabels(names,fontname = 'Arial', fontsize = 12) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/226777559.py:165: UserWarning: FixedFormatter should only be used together with FixedLocator ax4.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=12) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/226777559.py:168: UserWarning: FixedFormatter should only be used together with FixedLocator ax4.set_yticklabels(names,fontname = 'Arial', fontsize = 12) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/226777559.py:220: UserWarning: FixedFormatter should only be used together with FixedLocator ax5.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=12) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_72558/226777559.py:275: UserWarning: FixedFormatter should only be used together with FixedLocator ax6.set_xticklabels([-2,-1, 0, 1, 2],fontname = 'Arial', fontsize=12)
[0. 1. 1. 1. 0.] [0. 1. 1. 1. 0.] [1. 1. 1. 1. 1.]
Figure 3: Mean values and linear trends of frontal metrics by area. Panels a-c: Mean values of frontal density in % (the proportion of frontal pixels in a 3 × 3 kernel window), frontal frequency in % (the proportion of frontal occurrence within a year), and frontal strength in °C km-1, by area (see Methods: Statistical metrics). Panels d-f: Decadal linear trends of frontal density, frequency, and strength by area; standard errors are shown with black error bars, and statistically significant trend values (P < 0.05) are labelled with the trend value (i.e., trends are significant except for the global ocean and remaining areas in panel d and e). Bars and numbers in all panels are from MODIS satellite data (2003–2023).
fig = plt.figure(figsize=(10,6),dpi=400)
ax1 = fig.add_subplot(231)
ax2 = fig.add_subplot(232)
ax3 = fig.add_subplot(233)
ax4 = fig.add_subplot(234)
ax5 = fig.add_subplot(235)
ax6 = fig.add_subplot(236)
names = ['', 'Remaining','Declining','Intensifying','Key','Global Ocean']
########################################################################################################################
# Panel a
# calculate means
MFdens1_mean = MFdens1.mean()
MFdens2_mean = MFdens2.mean()
MFdens3_mean = MFdens3.mean()
MFdens4_mean = MFdens4.mean()
MFdens5_mean = MFdens5.mean()
EFdens1_mean = EFdens1.mean()
EFdens3_mean = EFdens3.mean()
MFdens=np.array([MFdens4_mean,MFdens3_mean,MFdens2_mean,MFdens1_mean,MFdens5_mean])
# bar plot
# rects = ax1.barh([1,2,3,4,5],MFdens,color = '#830783',alpha = 0.5,height = 0.3)
rects1 = ax1.barh([2],EFdens3_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
rects2 = ax1.barh([4],EFdens1_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# bar labels
# ax1.bar_label(rects,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#830783')
ax1.bar_label(rects1,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
ax1.bar_label(rects2,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# plot settings
ax1.xaxis.set_major_locator(MultipleLocator(10))
ax1.xaxis.set_minor_locator(MultipleLocator(5))
ax1.yaxis.set_major_locator(MultipleLocator(1))
ax1.set_yticklabels(names,fontname = 'Arial', fontsize = 12)
ax1.set_xticks([0,10,20,30,40,50])
ax1.set_xticklabels([0,10,20,30,40,50],fontname = 'Arial', fontsize = 12)
ax1.set_title(r"a",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax1.set_xlabel("%",fontname = 'Arial', fontsize = 12)
ax1.set_xlim(0,50)
ax1.set_ylim(0.5,5.5)
ax1.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel b
# calculate means
MFfreq1_mean = MFfreq1.mean()
MFfreq2_mean = MFfreq2.mean()
MFfreq3_mean = MFfreq3.mean()
MFfreq4_mean = MFfreq4.mean()
MFfreq5_mean = MFfreq5.mean()
EFfreq1_mean = EFfreq1.mean()
EFfreq3_mean = EFfreq3.mean()
MFfreq=np.array([MFfreq4_mean,MFfreq3_mean,MFfreq2_mean,MFfreq1_mean,MFfreq5_mean])
# bar plot
# rects = ax2.barh([1,2,3,4,5],MFfreq,color = '#830783',alpha = 0.5,height = 0.3)
rects1 = ax2.barh([2],EFfreq3_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
rects2 = ax2.barh([4],EFfreq1_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# bar labels
# ax2.bar_label(rects,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#830783')
ax2.bar_label(rects1,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
ax2.bar_label(rects2,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# plot settings
ax2.xaxis.set_major_locator(MultipleLocator(10))
ax2.xaxis.set_minor_locator(MultipleLocator(5))
ax2.yaxis.set_major_locator(MultipleLocator(1))
ax2.set_yticklabels([],rotation=90, ha="center",va='top',fontname = 'Arial', fontsize = 15)
ax2.set_xticks([0,10,20,30,40])
ax2.set_xticklabels([0,10,20,30,40],fontname = 'Arial', fontsize = 12)
ax2.set_title(r"b",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax2.set_xlabel("%",fontname = 'Arial', fontsize = 12)
ax2.set_xlim(0,40)
ax2.set_ylim(0.5,5.5)
ax2.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel c
# calculate means
MFstre1_mean = MFstre1.mean()
MFstre2_mean = MFstre2.mean()
MFstre3_mean = MFstre3.mean()
MFstre4_mean = MFstre4.mean()
MFstre5_mean = MFstre5.mean()
EFstre1_mean = EFstre1.mean()
EFstre3_mean = EFstre3.mean()
MFstre=np.array([MFstre4_mean,MFstre3_mean,MFstre2_mean,MFstre1_mean,MFstre5_mean])
# bar plot
# rects = ax3.barh([1,2,3,4,5],MFstre,color = '#830783',alpha = 0.5,height = 0.3)
rects1 = ax3.barh([2],EFstre3_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
rects2 = ax3.barh([4],EFstre1_mean,color = '#0e8585',height = 0.3,alpha = 0.3)
# bar labels
# ax3.bar_label(rects,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#830783')
ax3.bar_label(rects1,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
ax3.bar_label(rects2,fontname = 'Arial', fontsize = 11,padding = 5,fmt=lambda x: f'{x:.2f}',color = '#0e8585')
# plot settings
ax3.xaxis.set_major_locator(MultipleLocator(0.5))
ax3.xaxis.set_minor_locator(MultipleLocator(0.25))
ax3.yaxis.set_major_locator(MultipleLocator(1))
ax3.set_yticklabels([], rotation=90,ha="center",va='top',fontname = 'Arial', fontsize = 12)
ax3.set_xticks([3.0,3.5,4.0,4.5,5.0])
ax3.set_xticklabels([3.0,3.5,4.0,4.5,5.0],fontname = 'Arial', fontsize = 12)
ax3.set_title(r"c",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax3.set_xlabel(" $\u00b0$C 100km$^{-1}$",fontname = 'Arial', fontsize = 12)
ax3.set_xlim(3,5)
ax3.set_ylim(0.5,5.5)
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(False)
formatter.set_powerlimits((-1,1))
ax3.xaxis.set_major_formatter(formatter)
ax3.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel d
pos = ax4.get_position()
new_pos = [pos.x0, pos.y0-0.07, pos.width, pos.height]
ax4.set_position(new_pos)
loc1 = [1,2,3,4,5]
MFdens_slopes=np.array([slope_MFdens4,slope_MFdens3, slope_MFdens2, slope_MFdens1, slope_MFdens5])*10*12 # decadal trend
# bar plot
# rects = ax4.barh([1,2,3,4,5],MFdens_slopes,color = '#830783',alpha = 0.5,height = 0.3)
rects1 = ax4.barh([2],slope_EFdens3*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
rects2 = ax4.barh([4],slope_EFdens1*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
# Make some labels.
# labels = [f'label{i}' for i in range(len(rects))]
# which = [1,2,3,4]
# for index, rect in enumerate(rects):
# if index in which:
# if MFdens_slopes[index]<0:
# ax4.text(rect.get_x() + rect.get_width()-1.5,loc1[index]-0.15,'{:,.2f}'.format(MFdens_slopes[index]),
# ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
# else:
# ax4.text(rect.get_x() + rect.get_width()+1.2,loc1[index]-0.15,'+{:,.2f}'.format(MFdens_slopes[index]),
# ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
ax4.text(-3.2, 1.4,'{:,.2f}'.format(slope_EFdens3*10*365),
ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
ax4.text(-2.4, 4.2,'{:,.2f}'.format(slope_EFdens1*10*365),
ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# calculate trend significance and plot errorbar
integrated_timeseries = [MFdens4_da,MFdens3_da, MFdens2_da, MFdens1_da, MFdens5_da]
integrated_timeseries_dataarray = xr.concat(integrated_timeseries, dim='x')
hypothesis,n_effective = significance_mk(integrated_timeseries_dataarray)
dynamical_region_std=np.std(integrated_timeseries,axis=1)
dynamical_region_err=1.96*(dynamical_region_std/np.sqrt(n_effective))
# for ii in range(1,6):
# plot_barhs(ax4,ii,MFdens_slopes[ii-1],dynamical_region_err[ii-1],width=0.05,linestyle='-',color='black',linewidth=1)
err_Fdens_extra = np.array([0.41949977, 0.32450672])
plot_barhs(ax4,2,slope_EFdens3*10*365,err_Fdens_extra[1],width=0.05,linestyle='-',color='black',linewidth=1)
plot_barhs(ax4,4,slope_EFdens1*10*365,err_Fdens_extra[0],width=0.05,linestyle='-',color='black',linewidth=1)
# plot settings
ax4.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=10)
ax4.xaxis.set_major_locator(MultipleLocator(2))
ax4.xaxis.set_minor_locator(MultipleLocator(1))
ax4.set_yticklabels(names,fontname = 'Arial', fontsize = 12)
ax4.set_title(r"d",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(True)
formatter.set_powerlimits((-1,1))
ax4.xaxis.set_major_formatter(formatter)
ax4.set_xlim(-5,5)
ax4.set_ylim(0.5,5.5)
ax4.set_xlabel('% decade$^{-1}$',fontname = 'Arial', fontsize=12)
ax4.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel e
pos = ax5.get_position()
new_pos = [pos.x0, pos.y0-0.07, pos.width, pos.height]
ax5.set_position(new_pos)
MFfreq_slopes=np.array([slope_MFfreq4,slope_MFfreq3, slope_MFfreq2, slope_MFfreq1, slope_MFfreq5])*10 # decadal trend
# bar plot
# rects = ax5.barh([1,2,3,4,5],MFfreq_slopes,color = '#830783',alpha = 0.5,height = 0.3)
rects1 = ax5.barh([2],slope_EFfreq3*10*12,color = '#0e8585',height = 0.3, alpha = 0.3)
rects2 = ax5.barh([4],slope_EFfreq1*10*12,color = '#0e8585',height = 0.3, alpha = 0.3)
# Make some labels.
# labels = [f'label{i}' for i in range(len(rects))]
# which = [1,2,3,4]
# for index, rect in enumerate(rects):
# if index in which:
# if MFfreq_slopes[index]<0:
# ax5.text(rect.get_x() + rect.get_width()-2,loc1[index]-0.15,'{:,.2f}'.format(MFfreq_slopes[index]),
# ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
# else:
# ax5.text(rect.get_x() + rect.get_width()+1.8,loc1[index]-0.15,'+{:,.2f}'.format(MFfreq_slopes[index]),
# ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
ax5.text(-5, 1.4,'{:,.2f}'.format(slope_EFfreq3*10*12),
ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
ax5.text(-3, 4.2,'{:,.2f}'.format(slope_EFfreq1*10*12),
ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# calculate trend significance and plot errorbar
integrated_timeseries = [MFfreq4_da,MFfreq3_da, MFfreq2_da, MFfreq1_da, MFfreq5_da]
integrated_timeseries_dataarray = xr.concat(integrated_timeseries, dim='x')
hypothesis,n_effective = significance_mk(integrated_timeseries_dataarray)
dynamical_region_std=np.std(integrated_timeseries,axis=1)
dynamical_region_err=1.96*(dynamical_region_std/np.sqrt(n_effective))
# for ii in range(1,6):
# plot_barhs(ax5,ii,MFfreq_slopes[ii-1],dynamical_region_err[ii-1],width=0.05,linestyle='-',color='black',linewidth=1)
err_Ffreq_extra = np.array([0.49811791, 0.34789087])
plot_barhs(ax5,2,slope_EFfreq3*10*12,err_Ffreq_extra[1],width=0.05,linestyle='-',color='black',linewidth=1)
plot_barhs(ax5,4,slope_EFfreq1*10*12,err_Ffreq_extra[0],width=0.05,linestyle='-',color='black',linewidth=1)
# plot settings
ax5.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=12)
ax5.xaxis.set_major_locator(MultipleLocator(3))
ax5.xaxis.set_minor_locator(MultipleLocator(1.5))
ax5.set_yticklabels([],rotation=90, ha="center",va='top',fontname = 'Arial', fontsize=12)
ax5.set_title(r"e",fontname = 'Arial', fontsize=18,fontweight = 'bold', loc='left')
ax5.set_xlim(-7,7)
ax5.set_ylim(0.5,5.5)
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(True)
formatter.set_powerlimits((-1,1))
ax5.xaxis.set_major_formatter(formatter)
ax5.set_xlabel('% decade$^{-1}$',fontname = 'Arial', fontsize=12)
ax5.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Panel f
pos = ax6.get_position()
new_pos = [pos.x0, pos.y0-0.07, pos.width, pos.height]
ax6.set_position(new_pos)
MFstre_slopes=np.array([slope_MFstre4,slope_MFstre3, slope_MFstre2, slope_MFstre1, slope_MFstre5])*10*12 # decadal trend
# bar plot
# rects = ax6.barh([1,2,3,4,5],MFstre_slopes,color = '#830783',alpha = 0.5,height = 0.3)
rects1 = ax6.barh([2],slope_EFstre3*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
rects2 = ax6.barh([4],slope_EFstre1*10*365,color = '#0e8585',height = 0.3, alpha = 0.3)
# 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:
# if MFstre_slopes[index]<0:
# ax6.text(rect.get_x() + rect.get_width()-0.1,loc1[index]-0.15,'{:,.2f}'.format(MFstre_slopes[index]),
# ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
# else:
# ax6.text(rect.get_x() + rect.get_width()+0.1,loc1[index]-0.15,'+{:,.2f}'.format(MFstre_slopes[index]),
# ha='center', va='bottom',color = '#830783',fontname = 'Arial', fontsize = 11)
ax6.text(-0.25, 1.4,'{:,.2f}'.format(slope_EFstre3*10*365),
ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
ax6.text(-0.2, 4.2,'{:,.2f}'.format(slope_EFstre1*10*365),
ha='center', va='bottom',color = '#0e8585',fontname = 'Arial', fontsize = 11)
# calculate trend significance and plot errorbar
integrated_timeseries = [MFstre4_da,MFstre3_da, MFstre2_da, MFstre1_da, MFstre5_da]
integrated_timeseries_dataarray = xr.concat(integrated_timeseries, dim='x')
hypothesis,n_effective = significance_mk(integrated_timeseries_dataarray)
dynamical_region_std=np.std(integrated_timeseries,axis=1)
dynamical_region_err=1.96*(dynamical_region_std/np.sqrt(n_effective))
# for ii in range(1,6):
# plot_barhs(ax6,ii,MFstre_slopes[ii-1],dynamical_region_err[ii-1],width=0.05,linestyle='-',color='black',linewidth=1)
err_Fstre_extra = np.array([0.00033134, 0.00023301])
plot_barhs(ax6,2,slope_EFstre3*10*365,err_Fstre_extra[1]*100,width=0.05,linestyle='-',color='black',linewidth=1)
plot_barhs(ax6,4,slope_EFstre1*10*365,err_Fstre_extra[0]*100,width=0.05,linestyle='-',color='black',linewidth=1)
# plot settings
ax6.set_xticklabels([-2,-1, 0, 1, 2],fontname = 'Arial', fontsize=12)
ax6.xaxis.set_major_locator(MultipleLocator(0.2))
ax6.xaxis.set_minor_locator(MultipleLocator(0.1))
ax6.set_yticklabels([], rotation=90,ha="center",va='top',fontname = 'Arial', fontsize = 12)
ax6.set_title(r"f",fontname = 'Arial', fontsize=15,fontweight = 'bold',loc = 'left')
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(False)
formatter.set_powerlimits((-1,1))
ax6.xaxis.set_major_formatter(formatter)
ax6.set_xlim(-0.4,0.4)
ax6.set_ylim(0.5,5.5)
ax6.set_xlabel('$\u00b0$C 100km$^{-1}$ decade$^{-1}$',fontname = 'Arial', fontsize=12)
ax6.axvline(x=0, color='k', linestyle='-',linewidth = 0.5)
########################################################################################################################
# Add some labels
ax1.text(-32,2.5,'Mean', fontname = 'Arial', fontsize = 15, fontweight = 'bold',rotation = 90)
ax1.text(-32,-4.2,'Trend', fontname = 'Arial', fontsize = 15, fontweight = 'bold',rotation = 90)
ax1.text(7, 6.3,'Frontal density', fontname = 'Arial', fontsize = 15,fontweight = 'bold')
ax1.text(66, 6.3,'Frontal frequency', fontname = 'Arial', fontsize = 15,fontweight = 'bold')
ax1.text(126, 6.3,'Frontal strength', fontname = 'Arial', fontsize = 15,fontweight = 'bold')
########################################################################################################################
plt.savefig('../JPEG/Fig3_frontal_metrics_by_area_ESA.jpeg',dpi=400,bbox_inches='tight')
/var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_53076/2268700123.py:44: UserWarning: FixedFormatter should only be used together with FixedLocator ax1.set_yticklabels(names,fontname = 'Arial', fontsize = 12) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_53076/2268700123.py:168: UserWarning: FixedFormatter should only be used together with FixedLocator ax4.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=10) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_53076/2268700123.py:171: UserWarning: FixedFormatter should only be used together with FixedLocator ax4.set_yticklabels(names,fontname = 'Arial', fontsize = 12) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_53076/2268700123.py:223: UserWarning: FixedFormatter should only be used together with FixedLocator ax5.set_xticklabels([-3,-2,-1, 0.00,1,2,3],fontname = 'Arial', fontsize=12) /var/folders/fr/rwsbf6zj7qv0bm19q2wnmxmm0000gn/T/ipykernel_53076/2268700123.py:278: UserWarning: FixedFormatter should only be used together with FixedLocator ax6.set_xticklabels([-2,-1, 0, 1, 2],fontname = 'Arial', fontsize=12)
:)