"""Render the note's data-derived figures. Requires NumPy and Matplotlib.

Run after verify-robustness.py. SVG text stays editable. PNG is a share image.
"""
from pathlib import Path
import json
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.colors import TwoSlopeNorm

HERE=Path(__file__).resolve().parent
d=json.loads((HERE/'results.json').read_text())
c=next(x for x in d['cases'] if x['label']=='1235' and x['lambda']==.2)
bg='#0b1724';ink='#d5e5ef';muted='#a8c0d1';cyan='#7dd9e8';gold='#e1b78d'
plt.rcParams.update({'font.family':'DejaVu Sans','font.size':12,'text.color':ink,
                     'axes.labelcolor':muted,'xtick.color':muted,'ytick.color':muted,
                     'axes.edgecolor':'#385267','axes.facecolor':bg,'figure.facecolor':bg,
                     'savefig.facecolor':bg,'svg.fonttype':'none','svg.hashsalt':'graviton-note-02'})

fig,(ax,bx)=plt.subplots(2,1,figsize=(12,7.6),gridspec_kw={'height_ratios':[2,1]},layout='constrained')
ax.plot(d['plot_times'],d['baseline_mean_abs_trace'],color='#9ab4c6',ls='--',lw=1.7,label='Baseline')
ax.plot(d['plot_times'],c['mean_abs_trace'],color=cyan,lw=2,label='Added interaction')
ax.axvspan(12,24,color=cyan,alpha=.08);ax.axvspan(36,48,color=gold,alpha=.08)
ax.set(xlim=(0,48),ylim=(0,1.04),xlabel='Model time (ℏ = 1)',ylabel='Mean |Gᵢ(t)|')
ax.set_xticks([0,12,24,36,48]);ax.grid(alpha=.14);ax.legend(facecolor=bg,edgecolor='none',labelcolor=ink,loc='upper right')
ax.set_title('One interaction, four observation windows',loc='left',fontsize=20,pad=18)
vals=c['contrasts_by_step'][0];labels=['0–12','12–24','24–36','36–48']
bars=bx.bar(labels,vals,color=[cyan if v<0 else gold for v in vals],width=.52)
bx.axhline(0,color=muted,lw=.7);bx.set(ylabel='Contrast ΔD',xlabel='Observation window',ylim=(-.158,.038))
for bar,v in zip(bars,vals):
 bx.text(bar.get_x()+bar.get_width()/2,v+(.006 if v>=0 else -.009),f'{v:+.6f}',ha='center',va='bottom' if v>=0 else 'top',fontsize=11)
for a in (ax,bx):a.spines[['top','right']].set_visible(False)
fig.get_layout_engine().set(rect=(0,.07,1,.93))
fig.text(.07,.027,'P₁₂₃₅ · λ = +0.2 · RMS energy matched · β = 0 · Δt = 0.1\nGraviton Research Note 02 · finite-model calculation, no experimental data',color=muted,fontsize=10)
fig.savefig(HERE/'reference-comparison.svg',metadata={'Date':'2026-10-27','Creator':'Graviton; render-figures.py'})
fig.savefig(HERE/'reference-comparison.png',dpi=160)
plt.close(fig)

selected=[x for x in d['cases'] if x['lambda']==.2]
matrix=np.array([x['contrasts_by_step'][0] for x in selected])
fig,ax=plt.subplots(figsize=(8,12),layout='constrained')
im=ax.imshow(matrix,cmap='BrBG_r',norm=TwoSlopeNorm(0,vmin=-.25,vmax=.12),aspect='auto')
ax.set_yticks(range(30),[x['label'] for x in selected]);ax.set_xticks(range(4),labels)
ax.set(xlabel='Observation window',ylabel='Quartic indices',title='All 30 additions at λ = +0.2')
fig.colorbar(im,ax=ax,label='ΔD: perturbed minus baseline',shrink=.7)
fig.savefig(HERE/'interaction-map.svg',metadata={'Date':'2026-10-27','Creator':'Graviton; render-figures.py'})
plt.close(fig)

# Social preview: the trace is computed data, not a decorative waveform.
fig=plt.figure(figsize=(12,6.3),dpi=100,facecolor='#07111e')
fig.text(.06,.89,'G R A V I T O N',fontsize=22,color=ink)
fig.text(.06,.76,'RESEARCH NOTE 02  /  OCTOBER 2026',fontsize=12,color=muted)
fig.text(.06,.51,'When the observation window\nchanges the result.',fontsize=32,color=ink,linespacing=1.3)
ax=fig.add_axes([.06,.13,.88,.24]);ax.set_facecolor('#07111e')
ax.plot(d['plot_times'],d['baseline_mean_abs_trace'],color=muted,lw=1.1,ls='--',alpha=.7)
ax.plot(d['plot_times'],c['mean_abs_trace'],color=cyan,lw=1.7)
ax.set_xlim(0,48);ax.axis('off')
fig.text(.06,.045,'180 model settings · four windows · reproducible calculations',fontsize=13,color=muted)
fig.savefig(HERE/'social-preview.png',dpi=100,facecolor='#07111e')
plt.close(fig)
for name in ('reference-comparison.svg','interaction-map.svg'):
    path=HERE/name
    path.write_text('\n'.join(line.rstrip() for line in path.read_text().splitlines())+'\n')
print('Rendered reference figure, interaction map and social preview from results.json.')
