Subsurface Oxygen \(O_2\)#

../../../_images/a17a4204b89b431c5c389826ab664e6f0e98ed438e7ee7395c0a9201619cac37.png

Figure. Change in Subsurface Oxygen from hindcast. The map (top) shows the change in subsurface oxygen concentration (µmol/L) in the vicinity of Palau over the period 1993-2022. The grey line is the Palau EEZ. The line plot (bottom) shows the change in subsurface oxygen concentration (µmol/L) averaged over the area within the top plot. The black line represents the trend, which is statistically significant (p < 0.05). The colored dots represent the 10 years with the lowest O2 on record.

Hide code cell source
import warnings
warnings.filterwarnings("ignore")
import os
import os.path as op
import sys

import pandas as pd
import numpy as np
import xarray as xr
import geopandas as gpd
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from myst_nb import glue 

sys.path.append("../../../../indicators_setup")

from ind_setup.plotting_int import plot_timeseries_interactive, plot_oni_index_th
from ind_setup.plotting import plot_base_map, plot_map_subplots, add_oni_cat, plot_bar_probs, fontsize

sys.path.append("../../../functions")
from data_downloaders import download_oni_index
from ocean import process_trend_with_nan

Setup#

Define area of interest

#Area of interest
lon_range  = [129.4088, 137.0541]
lat_range = [1.5214, 11.6587]

EEZ shapefile

path_figs = "../../../matrix_cc/figures"
shp_f = op.join(os.getcwd(), '..', '..','..', 'data/Palau_EEZ/pw_eez_pol_april2022.shp')
shp_eez = gpd.read_file(shp_f)

Load Data#

Superficial depth

data_xr = xr.open_dataset(op.join(os.getcwd(), '..', '..','..', 'data/data_phyc_o2_ph.nc'))#.isel(depth = 0).drop('depth')
dataset_id = 'o2'
label = 'O2 [µmol/l]'

Analysis#

Plotting#

Average#

fig, ax = plot_base_map(shp_eez = shp_eez, figsize = [10, 6])
im = ax.pcolor(data_xr.longitude, data_xr.latitude, data_xr.mean(dim='time')[dataset_id], transform=ccrs.PlateCarree(), 
                cmap = 'BuPu', 
                vmin = np.nanpercentile(data_xr.mean(dim = 'time')[dataset_id], 1), 
                vmax = np.nanpercentile(data_xr.mean(dim = 'time')[dataset_id], 99))
ax.set_extent([lon_range[0], lon_range[1], lat_range[0], lat_range[1]], crs=ccrs.PlateCarree())
plt.colorbar(im, ax=ax, label= label)
glue("average_map", fig, display=False)
plt.savefig(op.join(path_figs, 'F17_O2_mean_map.png'), dpi=300, bbox_inches='tight')
../../../_images/a17a4204b89b431c5c389826ab664e6f0e98ed438e7ee7395c0a9201619cac37.png

Change#

trend_m, _, _, _, _ = process_trend_with_nan(data_xr[dataset_id])

fig, ax = plot_base_map(shp_eez = shp_eez, figsize = [10, 6])
im = ax.pcolor(data_xr.longitude, data_xr.latitude, 
               trend_m,
                transform=ccrs.PlateCarree(), 
                cmap = 'RdBu_r', 
                vmin = -3,
                vmax = 3,
                )
ax.set_extent([lon_range[0], lon_range[1], lat_range[0], lat_range[1]], crs=ccrs.PlateCarree())
plt.colorbar(im, ax=ax, label=  dataset_id)
plt.savefig(op.join(path_figs, 'F17_O2_mean_map_trend.png'), dpi=300, bbox_inches='tight')
../../../_images/525b72108f7a3c4f838837f0666a65cde80b04339e26b218c39ef876c85c89bc.png

Seasonal average#

data_month = data_xr.groupby('time.season').mean().sel(season = ['DJF', 'MAM', 'JJA', 'SON'])
im = plot_map_subplots(data_month, dataset_id, shp_eez = shp_eez, cmap = 'BuPu', 
                  vmin = np.nanpercentile(data_month.min(dim = 'season')[dataset_id], 1), 
                  vmax = np.nanpercentile(data_month.max(dim = 'season')[dataset_id], 99),
                  figsize = (15,11), sub_plot = [1, 4], cbar_pad = 0.05, cbar = 1)
../../../_images/fdbecaecb91e667e503a4ac1905f6bef06f2277d93d2d1b47b4926fc628740d3.png

Seasonal anomaly#

data_month = data_xr.groupby('time.season').mean().sel(season = ['DJF', 'MAM', 'JJA', 'SON']) - data_xr.mean(dim='time')
im = plot_map_subplots(data_month, dataset_id, shp_eez = shp_eez, 
                  cmap = 'RdBu_r', vmin=-1.2, vmax=1.2,
                  figsize = (15,11), sub_plot = [1, 4], cbar_pad = 0.05,
                  cbar = 1)
../../../_images/ede693297448619d41952146ab2c87397d24299a537e6eced6d3ad7c854fe835.png

Annual average#

data_y = data_xr.resample(time='1YE').mean()
im = plot_map_subplots(data_y, dataset_id, shp_eez = shp_eez, cmap = 'BuPu', 
                  vmin = np.nanpercentile(data_xr.min(dim = 'time')[dataset_id], 1), 
                  vmax = np.nanpercentile(data_xr.max(dim = 'time')[dataset_id], 99),
                  cbar = 1)
../../../_images/d163ecb51f233a112e2af737860f0e746ba3e80906a82093383d922bf0feef2d.png

Annual anomaly#

data_an = data_y - data_xr.mean(dim='time')
fig = plot_map_subplots(data_an, dataset_id, shp_eez = shp_eez, cmap='RdBu_r', vmin=-2, vmax=2, cbar = 1)
../../../_images/50d6924b3789d366445961859d6a3266d02366a291d991cbee70b684504cc75e.png

Average over area#

dict_plot = [{'data' : data_xr.mean(dim = ['longitude', 'latitude']).to_dataframe(), 
              'var' : dataset_id, 'ax' : 1, 'label' : f'{label} - MEAN AREA'},]
fig, trend = plot_timeseries_interactive(dict_plot, trendline=True, return_trend=True, scatter_dict = None, figsize = (25, 12), label_yaxes = label);
fig.write_html(op.join(path_figs, 'F17_O2_mean_trend.html'), include_plotlyjs="cdn")

Seasonal variability#

fig, ax = plt.subplots(figsize=(12,2))
data_xr.mean(dim = ['longitude', 'latitude']).groupby('time.month').mean()[dataset_id].plot(ax = ax, marker = 'o', color = 'k')
[<matplotlib.lines.Line2D at 0x1887074d0>]
../../../_images/0edf1418c8266aa15f7a15b439cd739add9ecccb14e18439d82e76a50a60f232.png

Timeseries at a given point#

loc = [7.37, 134.7]
dict_plot = [{'data' : data_xr.sel(longitude=loc[1], latitude=loc[0], method='nearest').to_dataframe(), 
              'var' : dataset_id, 'ax' : 1, 'label' : f'{label} at [{loc[0]}, {loc[1]}]'},]
fig, ax = plot_base_map(shp_eez = shp_eez, figsize = [10, 6])
ax.set_extent([lon_range[0], lon_range[1], lat_range[0], lat_range[1]], crs=ccrs.PlateCarree())
ax.plot(loc[1], loc[0], '*', markersize = 12, color = 'royalblue', transform=ccrs.PlateCarree(), label = 'Location Analysis')
ax.legend()
<matplotlib.legend.Legend at 0x187ced760>
../../../_images/038a2757803511e8b284fa11a57d0ba084269dbabe56e09215299e69572e231d.png
fig = plot_timeseries_interactive(dict_plot, trendline=True, scatter_dict = None, figsize = (25, 12), label_yaxes = label);

ONI index analysis#

p_data = 'https://psl.noaa.gov/data/correlation/oni.data'
df1 = download_oni_index(p_data)
lims = [-.5, .5]
plot_oni_index_th(df1, lims = lims)

Group by ONI category

df1 = add_oni_cat(df1, lims = lims)
df1['ONI'] = df1['oni_cat']
data_xr['ONI'] = (('time'), df1.iloc[np.intersect1d(data_xr.time, df1.index, return_indices=True)[2]].ONI.values)
data_xr['ONI_cat'] = (('time'), np.where(data_xr.ONI < lims[0], -1, np.where(data_xr.ONI > lims[1], 1, 0)))
data_oni = data_xr.groupby('ONI_cat').mean()

Average#

fig = plot_map_subplots(data_oni, dataset_id, shp_eez = shp_eez, cmap = 'BuPu', 
                  vmin = np.nanpercentile(data_xr.mean(dim = 'time')[dataset_id], 1) - 1, 
                  vmax = np.nanpercentile(data_xr.mean(dim = 'time')[dataset_id], 99) + 1,
                  sub_plot= [1, 3], figsize = (20, 9),  cbar = True, cbar_pad = 0.1,
                  titles = ['La Niña', 'Neutral', 'El Niño'],)
plt.savefig(op.join(path_figs, 'F17_O2_ENSO.png'), dpi=300, bbox_inches='tight')
../../../_images/00ae97286cec3b087f93cb4933d116fe951293858268ae3251abe7a2b5750147.png

Anomaly#

data_an = data_oni - data_xr.mean(dim='time')
fig = plot_map_subplots(data_an, dataset_id, shp_eez = shp_eez, cmap='RdBu_r', vmin=-1, vmax=1,
                  sub_plot= [1, 3], figsize = (20, 9),  cbar = True, cbar_pad = 0.1,
                  titles = ['La Niña', 'Neutral', 'El Niño'],)
../../../_images/55ac22afe0aa36c1442575ddfe7f3a784cc9475d2db2fda09299e20a5c1ae096.png

Table#

from ind_setup.tables import style_matrix, table_ocean
style_matrix(table_ocean(data_xr, trend[0], data_oni, dataset_id))
Key Metrics Summary
Metric Value
Monthly Average 200.018
Monthly Maximum 01/02/2019 203.530
Monthly Minimum 01/11/1998 196.795
Maximum Annual Average 201.180
Minimum Annual Average 198.524
Rate of change [µmol/l/year] -0.037
Change between 1993 and 2025 [µmol/l] -1.184
Average La Niña o2 199.736
Average El Niño o2 200.643
Average Neutral o2 199.932