import datetime as dt
from IPython.display import Image
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.colors as colors
import matplotlib.pyplot as plt
import xarray as xr
import cartopy
import cartopy.crs as ccrs
import matplotlib.cm as cmx
import matplotlib.ticker as mticker
import cartopy.feature as cfeature
import scipy.io as sio
import gsw
import seaborn
def datetime2doy(datetime):
doys = np.zeros_like(np.array(datetime))
for k in range(len(doys)):
y0=datetime[k].year
datetime_startofyear=dt.datetime(year=y0, month=1, day=1)
doys[k] = (datetime[k] - datetime_startofyear)/dt.timedelta(days=1)
return doys
def hrssince2datetime(hrs,epoch):
return epoch + dt.timedelta(hours=1) * hrs
import matplotlib.pyplot as plt
plt.close("all")
# for captioning and labelling output figures inside the notebook when published to latex
def latexImage(fname,label,caption,width=0.7):
display(Image(filename=fname,width=600),
metadata={"ipub":{
"figure":{
"caption":caption,
"label":label,
"width":width}}})
# Example of making your own norm. Also see matplotlib.colors.
# From Joe Kington: This one gives two different linear ramps:
class MidpointNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
colors.Normalize.__init__(self, vmin, vmax, clip)
def __call__(self, value, clip=None):
# I'm ignoring masked values and all kinds of edge cases to make a
# simple example...
x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
return np.ma.masked_array(np.interp(value, x, y))
import re
def tex_escape(text):
"""
:param text: a plain text message
:return: the message escaped to appear correctly in LaTeX
"""
conv = {
'&': r'\&',
'%': r'\%',
'$': r'\$',
'#': r'\#',
'_': r'\_',
'{': r'\{',
'}': r'\}',
'~': r'\textasciitilde{}',
'^': r'\^{}',
'\\': r'\textbackslash{}',
'<': r'\textless{}',
'>': r'\textgreater{}',
}
regex = re.compile('|'.join(re.escape(str(key)) for key in sorted(conv.keys(), key = lambda item: - len(item))))
return regex.sub(lambda match: conv[match.group()], text)
# returns: axes for cartopy plot
# and latlon2xy convenience function to convert latlon to chosen projection
def map_blueprint (plotbathymetry=False,printmap=True,plotstations=False,
fig=False,plotxlabels=True,plotylabels=True,
icecampmarker = True,
icecampmarkercolor='yellow',
label=0):
if not printmap:
plotbathymetry=False
plotstations=False
import matplotlib as mpl
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np
import cartopy.feature as cfeature
proj = ccrs.LambertConformal(central_longitude=-60, central_latitude=70,standard_parallels=(65,75))
if fig==False:
fig=plt.subplots()[0]
ax = plt.axes(projection = proj)
else:
ax = fig.add_axes([.1,.1,.8,.8],projection = proj,label='axes{:d}'.format(label))
hc=ax.coastlines(resolution='50m')
MapExtent = [-66,-53,67,71.5]
ax.set_extent(MapExtent, ccrs.PlateCarree())
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False,
linewidth=1, color='gray', alpha=0.5, linestyle='--')
gl.xlocator = mticker.FixedLocator([-75,-70,-65,-60,-55,-50,-45])
gl.ylocator = mticker.FixedLocator([60,64,67,68,69,70,71,72,76])
if plotxlabels:
# LONGITUDE LABELS
y0,_ = ax.get_ylim()
for lon in [-65,-60,-55]:
x0,_ = proj.transform_point(lon,MapExtent[2]-1,src_crs = ccrs.PlateCarree())
plt.text(x0,y0-1e4,'{:2d}$^\circ$W'.format(-lon),horizontalalignment = 'center',verticalalignment='top')
if plotylabels:
# LATITUDE LABELS
x0,_ = ax.get_xlim()
someLons = np.arange(-90,-40,1)
for lat in [68,69,70,71]:
# interpolate latitude circle to map boundary
xyzArray = proj.transform_points(ccrs.PlateCarree(),
someLons,lat*np.ones_like(someLons))
x = xyzArray[:,0]
y = xyzArray[:,1]
y0 = np.interp(x0,x,y)
plt.text(x0-1e4,y0,'{:2d}$^\circ$N'.format(lat),horizontalalignment = 'right',verticalalignment='center')
def latlon2xy(lon,lat):
xyz = proj.transform_points(ccrs.PlateCarree(),lon,lat).squeeze()
x,y,_ = np.split(xyz,3,axis=len(xyz.shape)-1)
x[np.isinf(x)]=np.nan
y[np.isinf(y)]=np.nan
return x.squeeze(),y.squeeze()
# ICE CAMP
if icecampmarker:
xIceCamp,yIceCamp = latlon2xy(np.array([-63.78953333]),np.array([67.47973333]))
ax.plot(xIceCamp,yIceCamp,'*',markeredgecolor='k',markerfacecolor=icecampmarkercolor,markersize=15)
# GE Stations
if plotstations:
ctd=pd.read_pickle('nb_temp/GE2016_Amundsen_hydrography_data.pandas')
ax.plot(*latlon2xy(np.array(ctd['Longitude']),np.array(ctd['Latitude'])),
'o',markeredgecolor='k',markerfacecolor='white',markersize=6)
if plotbathymetry:
import scipy.io as sio
top = sio.loadmat('/Users/doppler/database/IBCAO/IBCAO_1min_bathy.mat')
lonMap,latMap=np.meshgrid(top['x'],top['y'])
zMap=-top['IBCAO_1min']
xMap,yMap = latlon2xy(lonMap,latMap)
ax.contour(xMap,yMap,zMap,levels=[250,500],colors='gray',linewidths=1.5)
if not printmap: plt.close(fig)
return ax,latlon2xy,fig
_,latlon2xy,_=map_blueprint(printmap=False)
This document provides supplementary material to our study on Baffin Bay hydrography and the environmental constraints during a phytoplankton bloom at the retreating ice edge. It provides more detail on some of the methods, but mostly shows more variables that may help the interested reader in getting a better overview over the immense dataset the Green Edge campaign has produced. All data are accessible at the Green Edge database (\url{http://www.obs-vlfr.fr/proof/php/GREENEDGE/greenedge.php%7D).
This document was created as a Jupyter Lab notebook and exported to pdf partly using Chris Sewell's ipypublish template.
The following true color images are meant to provide more context for the campaign, especially with regards to floe sizes and general impressions of the ice cover that are hard to capture in sea ice concentration charts. Surface chlorophyll-a and sea temperature show the phytoplankton growth and warming trailing behind the retreating ice edge.
latexImage(fname='coauthor-contributions/laurent/MODIS_TRUE_COLOR_APRIL26.png',
caption='MODIS true color image from 26 April 2016. Markers show hydrographic stations.',
label='fig:modis1')
latexImage(fname='coauthor-contributions/laurent/MODIS_TRUE_COLOR_JUNE1.png',
caption='MODIS true color image from 1 June 2016. Markers show hydrographic stations.',
label='fig:modis2')
latexImage(fname='coauthor-contributions/laurent/MODIS_TRUE_COLOR_JULY11.png',
caption='MODIS true color image from 11 July 2016. Markers show hydrographic stations.',
label='fig:modis3')
latexImage(fname='coauthor-contributions/laurent/CHL_SST_AMU.png',
caption='Monthly averages of chlorophyll-a and sea surface temperature (SST) in Baffin Bay; \
the black line shows the ice edge.',
label='fig:chla-sst',width=1)