In [1]:
import os
from ioos_tools.ioos import parse_config, load_ncs
config = parse_config('config.yaml')
save_dir = os.path.join(os.path.abspath(config['run_name']))
In [2]:
import json
fname = os.path.join(config['run_name'], 'skill_score.json')
with open(fname, 'r') as f:
skill_score = json.loads(f.read())
In [3]:
import pandas as pd
mean_bias = pd.DataFrame.from_dict(skill_score['mean_bias'])
mean_bias = mean_bias.applymap('{:.2f}'.format).replace('nan', '--')
skill_score = pd.DataFrame.from_dict(skill_score['rmse'])
skill_score = skill_score.applymap('{:.2f}'.format).replace('nan', '--')
In [4]:
from ioos_tools.ioos import make_map
bbox = config['region']['bbox']
units = config['units']
run_name = config['run_name']
kw = dict(zoom_start=11, line=True, states=False,
secoora_stations=False, layers=False)
mapa = make_map(bbox, **kw)
In [5]:
from ioos_tools.ioos import stations_keys
all_obs = stations_keys(config)
In [6]:
from glob import glob
from operator import itemgetter
import iris
import folium
from folium.plugins import MarkerCluster
iris.FUTURE.netcdf_promote = True
big_list = []
for fname in glob(os.path.join(save_dir, '*.nc')):
if 'OBS_DATA' in fname:
continue
cube = iris.load_cube(fname)
model = fname.split('-')[-1].split('.')[0]
lons = cube.coord(axis='X').points
lats = cube.coord(axis='Y').points
stations = cube.coord('station_code').points
models = [model]*lons.size
lista = zip(models, lons.tolist(), lats.tolist(), stations.tolist())
big_list.extend(lista)
big_list.sort(key=itemgetter(3))
df = pd.DataFrame(big_list, columns=['name', 'lon', 'lat', 'station'])
df.set_index('station', drop=True, inplace=True)
groups = df.groupby(df.index)
locations, popups = [], []
for station, info in groups:
sta_name = all_obs[station]
for lat, lon, name in zip(info.lat, info.lon, info.name):
locations.append([lat, lon])
name = os.path.split(name)[-1]
popups.append('[{}]: {}'.format(name, sta_name))
MarkerCluster(locations=locations, popups=popups).add_to(mapa)
Out[6]:
In [7]:
import warnings
# Suppresing warnings for a "pretty output."
# Remove this line to debug any possible issues.
warnings.simplefilter('ignore')
In [8]:
# Legend dictionary. If any new model is found we will use its filename as legend.
# Here we only provide some nice names for the models we expect to find.
titles = {
'coawst_4_use_best': 'COAWST_4',
'global': 'HYCOM',
'NECOFS_GOM3_FORECAST': 'NECOFS_GOM3',
'NECOFS_FVCOM_OCEAN_MASSBAY_FORECAST': 'NECOFS_MassBay',
'OBS_DATA': 'Observations'
}
In [9]:
from bokeh.resources import CDN
from bokeh.plotting import figure
from bokeh.embed import file_html
from bokeh.models import HoverTool
from itertools import cycle
from bokeh.palettes import Category20
from folium import IFrame
# Plot defaults.
colors = Category20[20]
colorcycler = cycle(colors)
tools = 'pan,box_zoom,reset'
width, height = 750, 250
def make_plot(df, station):
p = figure(
toolbar_location='above',
x_axis_type='datetime',
width=width,
height=height,
tools=tools,
title=str(station)
)
for column, series in df.iteritems():
series.dropna(inplace=True)
if not series.empty:
if 'OBS_DATA' not in column:
bias = mean_bias[str(station)][column]
skill = skill_score[str(station)][column]
line_color = next(colorcycler)
kw = dict(alpha=0.65, line_color=line_color)
else:
skill = bias = 'NA'
kw = dict(alpha=1, color='crimson')
line = p.line(
x=series.index,
y=series.values,
legend='%s' % titles.get(column, column),
line_width=5,
line_cap='round',
line_join='round',
**kw,
)
p.add_tools(HoverTool(tooltips=[('Name', '%s' % column),
('Bias', bias),
('Skill', skill)],
renderers=[line]))
return p
def make_marker(p, station):
lons = stations_keys(config, key='lon')
lats = stations_keys(config, key='lat')
lon, lat = lons[station], lats[station]
html = file_html(p, CDN, station)
iframe = IFrame(html, width=width+40, height=height+80)
popup = folium.Popup(iframe, max_width=2650)
icon = folium.Icon(color='green', icon='stats')
marker = folium.Marker(location=[lat, lon],
popup=popup,
icon=icon)
return marker
In [10]:
dfs = load_ncs(config)
for station in dfs:
sta_name = all_obs[station]
df = dfs[station]
if df.empty:
continue
p = make_plot(df, station)
maker = make_marker(p, station)
maker.add_to(mapa)
mapa
Out[10]: