File size: 2,883 Bytes
35ff794 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | """Plot matched central-pressure MAE and unshifted pressure-versus-time curves."""
import json
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
ROOT=Path(__file__).resolve().parents[1]
data=json.loads((ROOT/'evaluation/released_daily/released_daily_benchmark.json').read_text())
assert data['status']=='complete_verified'
fig,axes=plt.subplots(2,2,figsize=(12,8))
colors=['#66758b','#007d78']
for column,agency in enumerate(('JMA','USA')):
metric=next(m for m in data['metrics'] if m['key']=='pressure_'+agency+'_hpa')
assert metric['coverage']['storms']==40
axis=axes[0,column]
values=np.array([metric['values'][m] for m in ('1.1','1.2')])
intervals=np.array([metric['intervals'][m] for m in ('1.1','1.2')])
errors=np.stack([values-intervals[:,0],intervals[:,1]-values])
bars=axis.bar(['1.1','1.2 · mean of 50'],values,yerr=errors,color=colors,width=.52,capsize=5)
axis.bar_label(bars,labels=[f'{v:.2f}' for v in values],padding=5,fontweight='bold')
axis.set_ylim(0,20)
axis.set_title(f"{agency} pressure MAE · {metric['coverage']['daily_issues']} shared starts",loc='left',fontweight='bold',fontsize=12)
axis.set_ylabel('Central-pressure MAE (hPa) · lower is better')
lower=axes[1,column]
issue=data['pressure_curves'][0]
observed=np.array([np.nan if v is None else v for v in issue['observed'][agency]])
lower.plot(data['cohort']['leads_hours'],observed,label=agency+' best track',color='#253643',linewidth=2.2)
for model,color,style in zip(('1.1','1.2'),colors,('--','-')):
lower.plot(data['cohort']['leads_hours'],issue['forecasts'][model],label=model,color=color,linestyle=style,linewidth=2.2)
lower.set_xticks([6,24,48,72,96,120])
lower.set_title(issue['name']+' · '+issue['issue_time_utc'][:16].replace('T',' ')+' UTC',loc='left',fontsize=10)
lower.set_xlabel('Forecast lead (hours)')
lower.set_ylabel('Actual central pressure (hPa)')
lower.legend(frameon=False)
for a in (axis,lower):
a.spines[['top','right']].set_visible(False)
a.set_axisbelow(True);a.grid(axis='y',alpha=.15)
fig.suptitle('Trackformer 1.1 vs 1.2 | matched central pressure',x=.075,ha='left',fontsize=17,fontweight='bold')
fig.text(.075,.923,'Same exact valid times · daily → storm → equal storm · 40 storms · JMA and USA separate',color='#526174')
fig.text(.075,.025,'Slight descriptive mean improvement; paired difference intervals include zero. 95% whole-storm intervals.\nOverlay: first eligible frozen case, not a best example. Exact-time physical hPa curves; no shift or warping. Missing is not zero.',fontsize=9,color='#526174')
fig.subplots_adjust(left=.075,right=.98,top=.85,bottom=.12,hspace=.43,wspace=.25)
fig.savefig(ROOT/'evaluation/released_daily/pressure_comparison.png',dpi=180,facecolor='white')
|