#!/usr/bin/env python3 """Plot the October 2026 brief from its summary.json. Requires Matplotlib. python3 research_brief_figure.py --summary summary.json --output figures """ import argparse import json from pathlib import Path import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--summary', type=Path, required=True) parser.add_argument('--output', type=Path, default=Path('figures')) args = parser.parse_args() data = json.loads(args.summary.read_text(encoding='utf-8')) years = list(range(2020, 2026)) rows = {year: {} for year in years} for row in data['years']: if row['year'] in rows: rows[row['year']][row['status']] = row['records'] plt.rcParams.update({'font.family': 'DejaVu Sans', 'font.size': 13, 'svg.fonttype': 'none', 'svg.hashsalt': 'psilo-brief-2026-10'}) fig, ax = plt.subplots(figsize=(12, 7), layout='constrained') fig.set_facecolor('#f8faf7') ax.set_facecolor('#f8faf7') left = [0] * len(years) for status, label, color in [('published', 'Published', '#295643'), ('preprint', 'Preprints', '#91b08e'), ('clinical trial', 'Registrations', '#b28a50'), ('protocol', 'Other', '#64748b')]: values = [rows[year].get(status, 0) for year in years] ax.barh([str(year) for year in years], values, left=left, label=label, color=color, height=.6) left = [previous + current for previous, current in zip(left, values)] for index, total in enumerate(left): ax.text(total + 12, index, f'{total:,}', va='center', fontweight='bold', color='#1f352b') ax.set_xlim(0, max(1, max(left)) * 1.15) ax.set_xlabel('Indexed records (not independent studies)') ax.set_title('Recorded-year cohorts in the October 2026 index', loc='left', pad=35, fontweight='bold') ax.legend(loc='upper left', bbox_to_anchor=(0, 1.075), ncol=4, frameon=False, fontsize=11) ax.spines[['top', 'right', 'left']].set_visible(False) ax.tick_params(axis='y', length=0) ax.grid(axis='x', alpha=.15) ax.set_axisbelow(True) args.output.mkdir(parents=True, exist_ok=True) fig.savefig(args.output / 'records-by-year.svg', metadata={'Date': None, 'Title': 'Recorded-year cohorts in the October 2026 index', 'Description': 'Completed calendar years 2020–2025, separated by record status; counts describe the frozen bibliographic compilation.'}) fig.savefig(args.output / 'records-by-year.png', dpi=100) plt.close(fig) if __name__ == '__main__': main()