diff options
Diffstat (limited to 'viz/gen_fig3.py')
| -rw-r--r-- | viz/gen_fig3.py | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/viz/gen_fig3.py b/viz/gen_fig3.py new file mode 100644 index 0000000..6cdbbbb --- /dev/null +++ b/viz/gen_fig3.py @@ -0,0 +1,37 @@ +import matplotlib.pyplot as plt +import numpy as np + +fig, ax = plt.subplots(figsize=(8, 5), dpi=300) + +categories = ['Random Slicing\n(58% sliced words)', 'Clean Boundaries\n(0% sliced words)'] +ratios = [1.471, 1.311] +ci_lower = [1.368, 1.258] +ci_upper = [1.529, 1.402] + +errors = [ + [ratios[0] - ci_lower[0], ratios[1] - ci_lower[1]], + [ci_upper[0] - ratios[0], ci_upper[1] - ratios[1]] +] + +x = np.arange(len(categories)) +bars = ax.bar(x, ratios, yerr=errors, capsize=8, color=['#f59e0b', '#10b981'], width=0.45, alpha=0.9, ecolor='#1e293b') + +ax.axhline(1.0, color='#ef4444', linestyle='--', linewidth=1.5, label='Baseline (Ratio = 1.0, No Signal)') +ax.set_ylabel('Middle-Layer Norm Ratio (@ / #)', fontsize=12, fontweight='bold') +ax.set_title('Synthetic Frequency-Matched Pair Control (@ vs # at 0.1% Freq)', fontsize=13, fontweight='bold', pad=15) +ax.set_xticks(x) +ax.set_xticklabels(categories, fontsize=11, fontweight='bold') +ax.set_ylim(0.8, 1.7) +ax.grid(True, linestyle=':', alpha=0.6) +ax.legend(loc='upper right', frameon=True) + +for bar, r, l, u in zip(bars, ratios, ci_lower, ci_upper): + ax.annotate(f'Ratio: {r:.2f}x\n95% CI: [{l:.2f}, {u:.2f}]', + xy=(bar.get_x() + bar.get_width() / 2, u), + xytext=(0, 8), textcoords="offset points", + ha='center', va='bottom', fontsize=10, fontweight='bold', + bbox=dict(boxstyle='round,pad=0.3', facecolor='white', alpha=0.8, edgecolor='none')) + +plt.tight_layout() +plt.savefig('docs/assets/fig3_synthetic_pair.png', dpi=300) +print("Saved Fig 3") |
