{"id":"academic-plotting","name":"academic-plotting","summary":"研究文脈からML論文の出版品質の数値を生成します。紙のセクションや説明が与えられると、システムコンポーネントや関係を抽出し、Geminiを通じてアーキテクチャ図を作成します。","body":"# Academic Plotting for ML Papers\n\nGenerate publication-quality figures for ML/AI conference papers. Two distinct workflows:\n\n1. **Diagram figures** (architecture, system design, workflows, pipelines) — AI image generation via Gemini\n2. **Data figures** (line charts, bar charts, scatter plots, heatmaps, ablations) — matplotlib/seaborn\n\n## When to Use Which Workflow\n\n| Figure Type | Tool | Why |\n|-------------|------|-----|\n| Architecture / system diagram | Gemini (Workflow 1) | Complex spatial layouts with boxes, arrows, labels |\n| Workflow / pipeline / lifecycle | Gemini (Workflow 1) | Multi-step processes with connections |\n| Bar chart, line plot, scatter | matplotlib (Workflow 2) | Precise numerical data, reproducible |\n| Heatmap, confusion matrix | matplotlib/seaborn (Workflow 2) | Structured grid data |\n| Ablation table as chart | matplotlib (Workflow 2) | Grouped bars or line comparisons |\n| Pie / donut chart | matplotlib (Workflow 2) | Proportional data (use sparingly in ML papers) |\n| Training curves | matplotlib (Workflow 2) | Loss/accuracy over steps/epochs |\n\n**Rule of thumb**: If the figure has numerical axes, use matplotlib. If the figure has boxes and arrows, use Gemini.\n\n---\n\n## Step 0: Context Analysis & Extraction\n\nThe user will typically provide one of these inputs — not a ready-made specification:\n\n| Input Type | Example | What to Extract |\n|-----------|---------|-----------------|\n| Full paper / section draft | \"Here's our method section...\" | System components, their relationships, data flow |\n| Description paragraph | \"Our system has three layers that...\" | Key entities, hierarchy, connections |\n| Raw results / data table | \"MMLU: 85.2, HumanEval: 72.1...\" | Metrics, methods, comparison structure |\n| CSV / JSON data | Experiment log files | Variables, trends, grouping dimensions |\n| Vague request | \"Make a figure for the overview\" | Read surrounding paper context to infer content |\n\n### Extraction Workflow\n\n**For diagrams** (research context → architecture figure):\n\n1. **Read the provided context** — paper section, abstract, or description paragraph\n2. **Identify visual entities** — What are the main components/modules/stages?\n   - Look for: nouns that represent system parts, named modules, layers, stages\n   - Count them: if >8 top-level entities, consider grouping into sections\n3. **Identify relationships** — How do components connect?\n   - Look for: verbs describing data flow (\"sends to\", \"queries\", \"feeds into\")\n   - Classify: data flow (solid arrow), control flow (gray), error path (dashed red)\n4. **Determine layout pattern**:\n   - Sequential pipeline → left-to-right flow\n   - Layered architecture → horizontal bands stacked vertically\n   - Hub-and-spoke → central node with radiating connections\n   - Hierarchical → top-down tree\n5. **Assign colors** — One accent color per logical group/layer\n6. **Write every label exactly** — Extract exact terminology from the paper text\n\n**For data charts** (results → figure):\n\n1. **Read the provided data** — table, paragraph with numbers, CSV, or JSON\n2. **Identify dimensions**:\n   - What is being compared? (methods, models, configurations) → categorical axis\n   - What is the metric? (accuracy, loss, latency, F1) → value axis\n   - Is there a time/step dimension? → line plot\n   - Are there multiple metrics? → multi-panel or grouped bars\n3. **Choose chart type** automatically using this priority:\n   - Has a step/time axis → **line plot**\n   - Comparing N methods on M benchmarks → **grouped bar chart**\n   - Single ranking → **horizontal bar** (leaderboard)\n   - Correlation between two continuous variables → **scatter plot**\n   - Square matrix of values → **heatmap**\n   - Proportional breakdown → **stacked bar** (avoid pie charts)\n4. **Determine figure sizing** — Single column vs full width based on data density\n5. **Highlight \"our method\"** — Identify which entry is the paper's contribution and give it a distinct color\n\n### Auto-Detection Examples\n\n**Context → Diagram**: \"Our system has a Planner, Executor, and Verifier. Planner sends plans to Executor, Executor returns results to Verifier, Verifier feeds back to Planner on failure.\"\n→ 3 entities, cycle layout, dashed feedback arrow → **Workflow 1 (Gemini)**\n\n**Data → Chart**: \"GPT-4: MMLU 86.4, HumanEval 67.0. Ours: 88.1, 71.2. Llama-3: 79.3, 62.1.\"\n→ 3 methods × 2 benchmarks → **Workflow 2 (grouped bar)**, highlight \"Ours\" in coral\n\n---\n\n## Workflow 1: Architecture & System Diagrams (AI Image Generation)\n\nUse Gemini 3 Pro Image Preview to generate diagrams. **Choose a visual style first** — this is the single biggest factor in whether the figure looks professional or generic.\n\n### Visual Styles\n\nPick one style per paper (all figures should be consistent):\n\n#### Style A: \"Sketch / 简笔画\" (Hand-Drawn)\n\nWarm, approachable, memorable. Ideal for overview figures and system introductions. Looks like a whiteboard sketch refined by a designer.\n\n```\nVISUAL STYLE — HAND-DRAWN SKETCH:\n- Slightly irregular, hand-drawn line quality — lines wobble gently, not perfectly straight\n- Rounded, soft shapes with visible pen strokes (like drawn with a thick felt-tip marker)\n- Warm off-white background (#FAFAF7), NOT pure white\n- Fill colors are soft watercolor-like washes: muted blue (#D6E4F0), soft peach (#F5DEB3),\n  light sage (#D4E6D4), pale lavender (#E6DFF0)\n- Borders are dark charcoal (#2C2C2C) with 2-3px line weight, slightly uneven\n- Arrows are hand-drawn with slight curves, ending in simple open arrowheads (not filled triangles)\n- Text uses a rounded sans-serif font (like Comic Neue or Architects Daughter feel)\n- Small doodle-style icons inside boxes: a tiny gear ⚙ for processing, a lightbulb 💡 for ideas,\n  a magnifying glass 🔍 for search — rendered as simple line drawings, NOT emoji\n- Overall feel: a carefully drawn whiteboard diagram, clean but with personality\n- NO clip art, NO stock icons, NO photorealistic elements\n```\n\n#### Style B: \"Modern Minimal\" (Clean & Bold)\n\nConfident, authoritative. Best for method figures where precision matters.\n\n```\nVISUAL STYLE — MODERN MINIMAL:\n- Ultra-clean geometric shapes with crisp edges\n- Bold color blocks as backgrounds for sections — NOT just accent bars, but full section fills\n  using desaturated tones: slate blue (#E8EDF2), warm sand (#F5F0E8), cool mint (#E8F2EE)\n- Component boxes have ROUNDED CORNERS (12px radius), NO visible border — they float on\n  the section background using subtle shadow (1px, 4px blur, rgba(0,0,0,0.06))\n- ONE accent color per section used sparingly on key elements: Deep blue (#2563EB),\n  Emerald (#059669), Amber (#D97706), Rose (#E11D48)\n- Arrows are thin (1.5px), dark gray (#6B7280), with small filled circle at source\n  and clean arrowhead at target — NOT thick colored arrows\n- Typography: Inter or system sans-serif, title 600 weight, body 400 weight\n- Labels INSIDE boxes, not beside them\n- Generous whitespace — at least 24px between elements\n- NO decorative elements, NO icons — let the structure speak\n```\n\n#### Style C: \"Illustrated Technical\" (Icon-Rich)\n\nEngaging, explanatory. Good for tutorial-style papers and figures that need to be self-explanatory.\n\n```\nVISUAL STYLE — ILLUSTRATED TECHNICAL:\n- Each major component has a small MEANINGFUL ICON drawn in a consistent line-art style\n  (single color, 2px stroke, ~24x24px): brain icon for reasoning, database cylinder for storage,\n  arrow-loop for iteration, network nodes for communication\n- Components sit inside soft rounded rectangles with a LEFT COLOR STRIP (4px wide)\n- Background is pure white, but each logical group has a very faint colored region behind it\n  (#F8FAFC for blue group, #FFF8F0 for orange group)\n- Connections use CURVED bezier paths (not straight lines), colored by SOURCE component\n- Key data flows are THICKER (3px) than secondary flows (1px, dashed)\n- Small annotation badges on arrows: \"×N\" for repeated operations, \"optional\" in italics\n- Title labels are ABOVE each section in small caps, letter-spaced\n- Overall: like a well-designed API documentation diagram\n```\n\n#### Style D: \"Accent Bar\" (Classic Academic)\n\nThe default academic style. Safe for any venue, works well in grayscale.\n\n```\nVISUAL STYLE — CLASSIC ACCENT BAR:\n- Horizontal section bands stacked vertically, pale gray (#F7F7F5) fill\n- Thick colored LEFT ACCENT BAR (8px) distinguishes each section\n- Content boxes: white fill, thin #DDD border, 4px rounded corners\n- Section palette: Blue #4A90D9, Teal #5BA58B, Amber #D4A252, Slate #7B8794\n- Sans-serif typography (Helvetica/Arial), bold titles, regular body\n- Colored arrows match their SOURCE section\n- Clean, flat, zero decoration\n```\n\n### Curated Color Palettes\n\n**\"Ocean Dusk\"** (professional, calming — default recommendation):\n`#264653` deep teal, `#2A9D8F` teal, `#E9C46A` gold, `#F4A261` sandy orange, `#E76F51` burnt coral\n\n**\"Ink & Wash\"** (for 简笔画 style):\n`#2C2C2C` charcoal ink, `#D6E4F0` washed blue, `#F5DEB3` washed wheat, `#D4E6D4` washed sage, `#E6DFF0` washed lavender\n\n**\"Nord\"** (for modern minimal):\n`#2E3440` polar night, `#5E81AC` frost blue, `#A3BE8C` aurora green, `#EBCB8B` aurora yellow, `#BF616A` aurora red\n\n**\"Okabe-Ito\"** (universal colorblind-safe, required for data charts):\n`#E69F00` orange, `#56B4E9` sky blue, `#009E73` green, `#F0E442` yellow, `#0072B2` blue, `#D55E00` vermillion, `#CC79A7` pink\n\n### Checklist\n\n- [ ] **Extract from context**: Read paper/description, identify entities and relationships\n- [ ] **Choose visual style** (A/B/C/D) — match the paper's tone and venue\n- [ ] **Choose color palette** — or use one consistent with existing paper figures\n- [ ] Obtain Gemini API key (`GEMINI_API_KEY` env var)\n- [ ] Write a detailed prompt: style block + layout + connections + constraints\n- [ ] Generate script at `figures/gen_fig_<name>.py`, run for 3 attempts\n- [ ] Review, select best, save as `figures/fig_<name>.png`\n\n### Prompt Structure (6 Sections)\n\nEvery Gemini prompt must include these sections in order:\n\n```\n1. FRAMING (5 lines): \"Create a [STYLE_NAME]-style technical diagram for a\n   [VENUE] paper. The diagram should feel [ADJECTIVES]...\"\n\n2. VISUAL STYLE (20-30 lines): Copy the full style block from above (A/B/C/D).\n   This is the most important section — it determines the entire visual character.\n\n3. COLOR PALETTE (10 lines): Exact hex codes for every color used.\n\n4. LAYOUT (50-150 lines): Every component, box, section — exact text, spatial\n   arrangement, and grouping. Be exhaustively specific.\n\n5. CONNECTIONS (30-80 lines): Every arrow individually — source, target, style,\n   label, routing direction.\n\n6. CONSTRAINTS (10 lines): What NOT to include. Adapt per style — e.g., sketch\n   style allows slight irregularity but still no clip art.\n```\n\n### Generation Script Template\n\n```python\n#!/usr/bin/env python3\n\"\"\"Generate [FIGURE_NAME] diagram using Gemini image generation.\"\"\"\nimport os, sys, time\nfrom google import genai\n\nAPI_KEY = os.environ.get(\"GEMINI_API_KEY\")\nif not API_KEY:\n    print(\"ERROR: Set GEMINI_API_KEY environment variable.\")\n    print(\"  Get a key at: https://aistudio.google.com/apikey\")\n    sys.exit(1)\n\nMODEL = \"gemini-3-pro-image-preview\"\nOUTPUT_DIR = os.path.dirname(os.path.abspath(__file__))\nclient = genai.Client(api_key=API_KEY)\n\nPROMPT = \"\"\"\n[PASTE YOUR 6-SECTION PROMPT HERE]\n\"\"\"\n\ndef generate_image(prompt_text, attempt_num):\n    print(f\"\\n{'='*60}\\nAttempt {attempt_num}\\n{'='*60}\")\n    try:\n        response = client.models.generate_content(\n            model=MODEL,\n            contents=prompt_text,\n            config=genai.types.GenerateContentConfig(\n                response_modalities=[\"IMAGE\", \"TEXT\"],\n            ),\n        )\n        output_path = os.path.join(OUTPUT_DIR, f\"fig_NAME_attempt{attempt_num}.png\")\n        for part in response.candidates[0].content.parts:\n            if part.inline_data:\n                with open(output_path, \"wb\") as f:\n                    f.write(part.inline_data.data)\n                print(f\"Saved: {output_path} ({os.path.getsize(output_path):,} bytes)\")\n                return output_path\n            elif part.text:\n                print(f\"Text: {part.text[:300]}\")\n        print(\"WARNING: No image in response\")\n        return None\n    except Exception as e:\n        print(f\"ERROR: {e}\")\n        return None\n\ndef main():\n    results = []\n    for i in range(1, 4):\n        if i > 1:\n            time.sleep(2)\n        path = generate_image(PROMPT, i)\n        if path:\n            results.append(path)\n    if not results:\n        print(\"All attempts failed!\")\n        sys.exit(1)\n    print(f\"\\nGenerated {len(results)} attempts. Review and pick the best.\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\n### Key Rules\n\n- **Always 3 attempts** — quality varies significantly between runs\n- **Style block is mandatory** — without it, Gemini defaults to generic corporate look\n- **Never hardcode API keys** — use `os.environ.get(\"GEMINI_API_KEY\")`\n- **Save generation scripts** — reproducibility is critical\n- **Specify every label exactly** — Gemini may misspell or rearrange text\n\n**Full prompt examples per style**: See [references/diagram-generation.md](references/diagram-generation.md)\n\n---\n\n## Workflow 2: Data-Driven Charts (matplotlib/seaborn)\n\nFor any figure with numerical data, axes, or quantitative comparisons.\n\n### Checklist\n\n- [ ] **Extract from context**: Parse results/data, identify methods, metrics, and comparison structure\n- [ ] **Auto-select chart type** based on data dimensions (see decision guide below)\n- [ ] Prepare data (CSV, dict, or inline arrays)\n- [ ] Apply publication styling (fonts, colors, sizes)\n- [ ] Highlight \"our method\" with a distinct color\n- [ ] Export as both PDF (vector) and PNG (300 DPI)\n- [ ] Verify LaTeX font compatibility\n- [ ] Save script at `figures/gen_fig_<name>.py`\n\n### Chart Type Decision Guide\n\n| Data Pattern | Best Chart | Notes |\n|-------------|------------|-------|\n| Trend over time/steps | Line plot | Training curves, scaling laws |\n| Comparing categories | Grouped bar chart | Model comparisons, ablations |\n| Distribution | Violin / box plot | Score distributions across methods |\n| Correlation | Scatter plot | Embedding analysis, metric correlation |\n| Grid of values | Heatmap | Attention maps, confusion matrices |\n| Part of whole | Stacked bar (not pie) | Prefer stacked bar over pie in ML papers |\n| Many methods, one metric | Horizontal bar | Leaderboard-style comparisons |\n\n### Publication Styling Template\n\n```python\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# --- Publication defaults (polished, not generic) ---\nplt.rcParams.update({\n    \"font.family\": \"serif\", \"font.serif\": [\"Times New Roman\", \"DejaVu Serif\"],\n    \"font.size\": 10, \"axes.titlesize\": 11, \"axes.titleweight\": \"bold\",\n    \"axes.labelsize\": 10, \"legend.fontsize\": 8.5, \"legend.frameon\": False,\n    \"figure.dpi\": 300, \"savefig.dpi\": 300, \"savefig.bbox\": \"tight\",\n    \"axes.spines.top\": False, \"axes.spines.right\": False,\n    \"axes.grid\": True, \"grid.alpha\": 0.15, \"grid.linestyle\": \"-\",\n    \"lines.linewidth\": 1.8, \"lines.markersize\": 5,\n})\n\n# --- \"Ocean Dusk\" palette (professional, distinctive, colorblind-safe) ---\nCOLORS = [\"#264653\", \"#2A9D8F\", \"#E9C46A\", \"#F4A261\", \"#E76F51\",\n          \"#0072B2\", \"#56B4E9\", \"#8C8C8C\"]\nOUR_COLOR = \"#E76F51\"       # coral — warm, stands out\nBASELINE_COLOR = \"#B0BEC5\"  # cool gray — recedes\nFIG_SINGLE, FIG_FULL = (3.25, 2.5), (6.75, 2.8)\n```\n\n### Common Chart Patterns\n\n**Line plot (training curves)** — with markers and confidence bands:\n\n```python\nfig, ax = plt.subplots(figsize=FIG_SINGLE)\nmarkers = [\"o\", \"s\", \"^\", \"D\", \"v\"]\nfor i, (method, (mean, std)) in enumerate(results.items()):\n    color = OUR_COLOR if method == \"Ours\" else COLORS[i]\n    ax.plot(steps, mean, label=method, color=color,\n            marker=markers[i % 5], markevery=max(1, len(steps)//8),\n            markersize=4, zorder=3)\n    ax.fill_between(steps, mean - std, mean + std, color=color, alpha=0.12)\nax.set_xlabel(\"Training Steps\")\nax.set_ylabel(\"Accuracy (%)\")\nax.legend(loc=\"lower right\")\nfig.savefig(\"figures/fig_training.pdf\")\nfig.savefig(\"figures/fig_training.png\", dpi=300)\n```\n\n**Grouped bar chart (ablation)** — with value labels:\n\n```python\nfig, ax = plt.subplots(figsize=FIG_FULL)\nx = np.arange(len(categories))\nn = len(methods)\nwidth = 0.7 / n\nfor i, (method, scores) in enumerate(methods.items()):\n    color = OUR_COLOR if method == \"Ours\" else COLORS[i]\n    offset = (i - n / 2 + 0.5) * width\n    bars = ax.bar(x + offset, scores, width * 0.9, label=method, color=color,\n                  edgecolor=\"white\", linewidth=0.5)\n    for bar, s in zip(bars, scores):\n        ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.3,\n                f\"{s:.1f}\", ha=\"center\", va=\"bottom\", fontsize=7, color=\"#444\")\nax.set_xticks(x)\nax.set_xticklabels(categories)\nax.set_ylabel(\"Score\")\nax.legend(ncol=min(n, 4))\nfig.savefig(\"figures/fig_ablation.pdf\")\n```\n\n**Heatmap** — with diverging colormap and clean borders:\n\n```python\nimport seaborn as sns\nfig, ax = plt.subplots(figsize=(4, 3.5))\nsns.heatmap(matrix, annot=True, fmt=\".2f\", cmap=\"YlOrRd\", ax=ax,\n            cbar_kws={\"shrink\": 0.75, \"aspect\": 20},\n            linewidths=1.5, linecolor=\"white\",\n            annot_kws={\"size\": 8, \"weight\": \"medium\"})\nax.set_xlabel(\"Predicted\")\nax.set_ylabel(\"Actual\")\nfig.savefig(\"figures/fig_confusion.pdf\")\n```\n\n**Horizontal bar (leaderboard)** — with \"our method\" highlight:\n\n```python\nfig, ax = plt.subplots(figsize=FIG_SINGLE)\ny_pos = np.arange(len(models))\ncolors = [BASELINE_COLOR] * len(models)\ncolors[our_idx] = OUR_COLOR\nbars = ax.barh(y_pos, scores, color=colors, height=0.55,\n               edgecolor=\"white\", linewidth=0.5)\nax.set_yticks(y_pos)\nax.set_yticklabels(models)\nax.set_xlabel(\"Accuracy (%)\")\nax.invert_yaxis()\nfor bar, s in zip(bars, scores):\n    ax.text(bar.get_width() + 0.3, bar.get_y() + bar.get_height()/2,\n            f\"{s:.1f}\", va=\"center\", fontsize=8, color=\"#444\")\nfig.savefig(\"figures/fig_leaderboard.pdf\")\n```\n\n**Full pattern library** (scaling laws, violin plots, multi-panel, radar): See [references/data-visualization.md](references/data-visualization.md)\n\n---\n\n## Publication Style Quick Reference\n\n| Venue | Single Col | Full Width | Font |\n|-------|-----------|------------|------|\n| NeurIPS | 5.5 in | 5.5 in | Times |\n| ICML | 3.25 in | 6.75 in | Times |\n| ICLR | 5.5 in | 5.5 in | Times |\n| ACL | 3.3 in | 6.8 in | Times |\n| AAAI | 3.3 in | 7.0 in | Times |\n\n**Always export PDF** for vector quality. PNG only for AI-generated diagrams.\n\n**Venue-specific details, LaTeX integration, font matching, accessibility checklist**: See [references/style-guide.md](references/style-guide.md)\n\n---\n\n## Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| Fonts look wrong in LaTeX | Export PDF, set `text.usetex=True`, or use `font.family=serif` |\n| Figure too large for column | Check venue width limits, use `figsize` in inches |\n| Colors indistinguishable in print | Use colorblind-safe palette + different line styles/markers |\n| Gemini misspells labels | Spell out every label exactly in prompt, add \"SPELL EXACTLY\" constraint |\n| Gemini ignores style | Add more negative constraints, be more specific about hex colors |\n| Blurry figures in PDF | Export as PDF (vector), not PNG; or use 300+ DPI for PNG |\n| Legend overlaps data | Use `bbox_to_anchor`, `loc=\"upper left\"`, or external legend |\n| Too many tick labels | Use `ax.xaxis.set_major_locator(MaxNLocator(5))` |\n\n## When to Use vs Alternatives\n\n| Need | This Skill | Alternative |\n|------|-----------|-------------|\n| Architecture diagrams | Gemini generation | TikZ (manual), draw.io (interactive), Mermaid (simple) |\n| Data charts | matplotlib/seaborn | Plotly (interactive), R/ggplot2 (statistics-heavy) |\n| Full paper writing | Use with `ml-paper-writing` | — |\n| Poster figures | Larger fonts, wider | `latex-posters` skill |\n| Presentation figures | Larger text, fewer details | PowerPoint/Keynote export |\n\n---\n\n## Quick Reference: File Naming Convention\n\n```\nfigures/\n├── gen_fig_<name>.py      # Generation script (always save for reproducibility)\n├── fig_<name>.pdf         # Final vector output (for LaTeX)\n├── fig_<name>.png         # Raster output (300 DPI, for AI-generated or fallback)\n└── fig_<name>_attempt*.png # Gemini attempts (keep for comparison)\n```","author":"@OpenRaiser","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/OpenRaiser/NanoResearch/tree/main/skills/vendor-ai-research/academic-plotting","license":"MIT","category":"data","lang":"en","tokens":5309,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/data-visualization.md","size":15393,"sha256":"680791b96eb8c3d6b065171f67c00ddfcd1b183629590a5df24182295fa2f013"},{"path":"references/diagram-generation.md","size":15426,"sha256":"9d5b1bb8a91b4cc04251cc89723784ebb3db176fa674632bc640c57d66a12f59"},{"path":"references/style-guide.md","size":8652,"sha256":"4d470b7bc178583c9f2649c34600d0cda6b78d4243d449afc056b4c1034cef18"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["aistudio.google.com"]}}