<jupyter_start><jupyter_text>Observed patterns in atmospheric CO2We use observations from nine deployments of three recent aircraft projects: the HIAPER Pole-to-Pole Observations (HIPPO) project {cite:p}`Wofsy2011-zm`; the O2/N2 Ratio and CO2 Airborne Southern Ocean (ORCAS) study {cite:p}`Stephens2018-be`; and the Atmospheric Tomography (ATom) mission {cite:p}`Wofsy2018-oo`. We also examined 44 atmospheric CO2 records from surface monitoring stations in the high-latitude Southern Hemisphere, selecting and filtering the highest quality data. This notebook creates a figure summarizing these data. Additional details are provided in other notebooks:- [Airborne observations](obs-aircraft.ipynb)- [Surface observations](obs-surface.ipynb)- [Error analysis for surface observations](obs-surface-error.ipynb)- [Evaluation of diurnal variations in surface data](obs-surface-diurnal-variations.ipynb)- [Simulated distributions of CO2](obs-simulated-distributions.ipynb)<jupyter_code>%load_ext autoreload
%autoreload 2
import numpy as np

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib.lines import Line2D

import util
import figure_panels
import datasets<jupyter_output><empty_output><jupyter_text>Load obervational datasetsHere we make use of functions provided by the `datasets` module; see [API documentation](api-datasets.rst) for additional details.<jupyter_code>%%time
dsets = dict(
    ds_obs_aircraft=datasets.aircraft_sections(),
    ds_obs_srf_djf=datasets.obs_surface_stn_v_lat('djf'),
    ds_obs_srf_jja=datasets.obs_surface_stn_v_lat('jja'),
)
dsets<jupyter_output>CPU times: user 323 ms, sys: 10.3 ms, total: 333 ms
Wall time: 455 ms<jupyter_text>Fig. 1: Observed CO2 distributions over the Southern Ocean<jupyter_code>%%time
# set up canvas
fig = plt.figure(figsize=(10, 6)) #dpi=300)

# set up plot grid
gs_top = gridspec.GridSpec(nrows=1, ncols=3, 
                        width_ratios=(1, 1, 0.02), 
                        left=0, right=1, bottom=0.52, top=1.,
                        hspace=0.2, wspace=0.1,
                       )

gs_bot = gridspec.GridSpec(nrows=1, ncols=3, 
                        width_ratios=(1, 1, 0.02), 
                        left=0, right=1, bottom=0, top=0.4,
                        hspace=0.2, wspace=0.1,
                       )

axs = dict(
    section_DJF=plt.subplot(gs_top[0, 0]),
    section_JJA=plt.subplot(gs_top[0, 1]),
    surface_DJF=plt.subplot(gs_bot[0, 0]),
    surface_JJA=plt.subplot(gs_bot[0, 1]),        
)
caxs = dict(
    section=plt.subplot(gs_top[:, -1]),
)

#------------------------------------
#--- ORCAS Section
#------------------------------------

ds = dsets['ds_obs_aircraft']
ax = axs['section_DJF']

ndx = np.where(ds.campaigns == 'ORCAS')[0][0]
cf = ax.pcolormesh(
        ds.y, ds.z, ds.DCO2_binned.isel(time=ndx).squeeze(),
        norm=figure_panels.divnorm,
        cmap=figure_panels.cmap,
        shading='nearest',    
    )
cs = ax.contour(
    ds.LAT, ds.ALT, ds.THETA.isel(time=ndx).squeeze(),
    levels=np.arange(255., 350., 5.),
    linewidths=1,
    colors='gray')    
lb = plt.clabel(cs, fontsize=8, inline=True, fmt='%d')  

ax.set_title('Aircraft obs: CO$_2$ minus 295–305K mean (Jan-Feb 2016)')
ax.set_ylim((0, 10.5))
ax.set_xlim(-91.25, -28.75)
ax.set_ylabel('Altitude [km]')        


#------------------------------------
#--- ATom Section
#------------------------------------

ds = dsets['ds_obs_aircraft']
ax = axs['section_JJA']

ndx = np.where(ds.campaigns == 'ATom-1')[0][0]
cf = ax.pcolormesh(
        ds.y, ds.z, ds.DCO2_binned.isel(time=ndx).squeeze(),
        norm=figure_panels.divnorm,
        cmap=figure_panels.cmap,
        shading='nearest',
    )
cs = ax.contour(
    ds.LAT, ds.ALT, ds.THETA.isel(time=ndx).squeeze(),
    levels=np.arange(255., 350., 5.),
    linewidths=1,
    colors='gray')    
lb = plt.clabel(cs, fontsize=8, inline=True, fmt='%d') 

ax.set_title('Aircraft obs: CO$_2$ minus 295–305K mean (Aug 2016)')
ax.set_ylim((0, 10.5))
ax.set_xlim(-91.25, -28.75)
ax.set_yticklabels([])

cax = caxs['section']
plt.colorbar(cf, cax=cax)
cax.set_title('$\Delta$CO$_2$ [ppm]', loc='left')

#------------------------------------
#--- DJF Surface
#------------------------------------

ds = dsets['ds_obs_srf_djf']
ax = axs[f'surface_DJF']
figure_panels.stn_v_lat(ds.CO2, ax)   
ax.set_ylabel('')
ax.set_title(f'Surface obs: DJF CO$_2$ minus SPO (1999-2019)')
ax.set_xlim(-91.25, -28.75)
ax.set_ylabel('$\Delta_{ y}$CO$_2$ [ppm]')

#------------------------------------
#--- JJA Surface
#------------------------------------

ds = dsets['ds_obs_srf_jja']
ax = axs[f'surface_JJA']
figure_panels.stn_v_lat(ds.CO2, ax)   
ax.set_ylabel('')
ax.set_title(f'Surface obs: JJA CO$_2$ minus SPO (1999-2019)')
ax.set_xlim(-91.25, -28.75)
ax.set_yticklabels([])


marker_spec = figure_panels.marker_spec_co2_inst()
legend_elements = [Line2D([0], [0], label=inst, linestyle=None, **spec) 
                   for inst, spec in marker_spec.items() if inst != 'Multiple']
ax.legend(handles=legend_elements, ncol=1, 
          fontsize=8, loc=(1.02, 0), frameon=False);

plot_keys = [
    'section_DJF', 'section_JJA', 
    'surface_DJF', 'surface_JJA', 
]   
util.label_plots(fig, [axs[k] for k in plot_keys], xoff=-0.02, yoff=0.02)

util.savefig(f'co2-aircraft-surface-obs')<jupyter_output>CPU times: user 2.21 s, sys: 57.3 ms, total: 2.27 s
Wall time: 2.72 s
{'fraction_non_alphanumeric': 0.1946445060018467, 'fraction_numerical': 0.040997229916897505, 'mean_word_length': 3.0, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '327708', 'license': 'MIT', 'n_tokens_mistral': 2185, 'n_tokens_neox': 1992, 'n_words': 406, 'path': 'so-co2-airborne-obs/obs-main.ipynb', 'repo_name': 'mgrover1/so-co2-airborne-obs', 'size': '5415'}