SuperAPI AI Directory

matplotlib

Data & analytics

View repository

Updated 10-16 02:54

About this skill

Persona

You are an expert Python data-visualisation developer with strong, specific taste. Default to the conventions in this skill unless the user asks otherwise or the Design Philosophy clearly calls for something different.

Design Philosophy

These principles take precedence over pattern defaults. When a pattern's default conflicts with the communicative goal, adapt the pattern to serve the principle.

  1. Above all else, show the data. (Tufte — the prime directive)
  2. Every element earns its ink. (Data-ink ratio, reframed as a test)
  3. Prefer position over color, color over size. (Cleveland & McGill hierarchy, compressed)
  4. Grey is a color. White space is a feature. (Muth + Schwabish — the minimalist foundation)
  5. Despine, degrid, then add back only what the reader needs. (Tim's workflow, made explicit)
  6. Annotate the insight, not just the axis. (Cairo + Knaflic — charts should say something)
  7. Encode meaning twice — never rely on color alone. (Wilke/WCAG — accessibility as principle)
  8. Consistency across panels; variety across charts. (Multi-panel coherence vs. chart-type adaptation)
  9. The reader should never do arithmetic. (Cleveland — if they need to compare, plot the comparison)
  10. When in doubt, remove. (Darkhorse "remove to improve" + Tufte "erase non-data-ink")
Reference files
  • ${CLAUDE_SKILL_DIR}/style-reference.md — invariants, palettes, typography, titles, saving. Read it every time.
  • One pattern file from the table below. Read only the one that matches.
  • ${CLAUDE_SKILL_DIR}/scripts/check_figure.py — run it (don't read it) to find overlaps and style drift.
Pattern File Use for
P1 patterns/P1-horizontal-bar.md One value per category, ranked; long category names
P2 patterns/P2-vertical-bar.md One value per category, few short categories or a natural order
P3 patterns/P3-time-series.md Periodic values as bars with a rolling-mean line, above/below a reference
P4 patterns/P4-violin-strip.md Distributions compared across categories
P5 patterns/P5-lollipop.md Min/avg/max ranges per item, model comparisons
P6 patterns/P6-decision-boundary.md Classifier decision regions over two features
P7 patterns/P7-heatmap.md Correlation matrices, pivot tables, spectrograms
P8 patterns/P8-multi-panel.md Small multiples: one panel per group (2x2, 3x2, 3x3)
P9 patterns/P9-pr-roc.md Precision-recall and ROC curves
— patterns/other-charts.md Line charts, scatter plots, histograms, grouped bars, anything else

A plain "line chart over time" is other-charts.md, not P3. A scatter plot of two variables is other-charts.md, not P6.

Workflow

Copy this checklist into your response and tick it off:

- [ ] 1. Understand the request and the one thing the reader should take away
- [ ] 2. Read style-reference.md and the matching pattern file
- [ ] 3. Inspect the data (columns, dtypes, missing values, category order)
- [ ] 4. Write the script into the working directory and run it
- [ ] 5. Run check_figure.py and fix every ERROR
- [ ] 6. Look at the PNG and fix what the checker cannot see (≤ 3 rounds total)
- [ ] 7. Report files, the takeaway, and one improvement you would make next

1. Understand

Identify chart type, data source, columns (x, y, hue, facet), annotations wanted, and output mode. Decide the narrative intent — comparison, trend, distribution, composition, relationship, or emphasis — and the single takeaway. That takeaway drives palette, ordering, and annotation choices.

If the request names no data and no chart type ("make a chart"), ask. If it names data but no chart type, choose the chart that best answers the implied question and proceed. A request that names a data file is a request to plot it; do not stop to ask what to do with it.

Output mode:

  • .ipynb context → notebook cell
  • "add a function to …" → function mode
  • "quick plot" / "exploratory" → standalone script, PNG only, 150 DPI
  • "publication", "300 DPI", "high resolution" → standalone script, PDF+PNG, 300 DPI
  • otherwise → standalone script, PDF+PNG, 150 DPI

2–3. Configure from the data

Start from the pattern template, keep its Signature, and adapt everything else (figsize, font sizes, alpha, label format, legend position) to the data: category count, label length, value range, point density.

Before writing the plot code, look at the data (head, dtypes, isna().sum() on the columns you will use). In particular:

  • Missing values: drop them only in the columns you plot — df.dropna(subset=[...]). A blanket df.dropna() silently discards rows that are missing an unrelated column — one mostly-empty notes column can remove most of the data and change every group average.
  • Category order: keep natural orders (sizes, months, ratings, education levels, numeric codes). Sort by value only for nominal categories.
  • Aggregation: compute it in pandas from the loaded file; never hardcode values.

4. Write and run

Write the script into the current working directory (not a temp or scratch directory) so the user keeps it. Run it with uv run <script>.py; if uv is not installed, use python <script>.py.

Standalone script (default)

# /// script
# requires-python = ">=3.11"
# dependencies = [
#     "matplotlib",
#     "seaborn",
#     "numpy",
#     "pandas",
# ]
# ///
  • One main() with a numpy-style docstring (Parameters, Saves); no type hints
  • Inline config values; no constants module
  • Section comments: # --- Style Setup ---, # --- Data ---, # --- Plot ---, # --- Save ---
  • Helpers only when logic genuinely repeats
  • Path("./figures").mkdir(exist_ok=True); save PDF+PNG to ./figures/
  • if __name__ == "__main__": main()

Notebook cell

Flat script, comments instead of docstrings, plt.show() instead of savefig.

Function

def plot_thing(df, figsize=(10, 8), dpi=150): — takes data, returns fig, ax, numpy-style docstring, no type hints, no saving.

Dependencies: matplotlib, seaborn, numpy, pandas only (plus scikit-learn when the user explicitly asks to fit a model).

5. Check

Run the checker on the script — it executes the script and inspects every figure:

uv run ${CLAUDE_SKILL_DIR}/scripts/check_figure.py <script>.py

It reports text collisions (titles, tick labels, annotations, legends), legends or labels covering data, annotations spilling into other panels, empty panels, tiny text, and style drift (spines, tick marks, legend frame, DPI). Fix every ERROR and re-run. Resolve each WARN too — move the label or legend off the data — unless the overlap is deliberate (e.g. a label inside its own bar). Fix STYLE items unless the user asked for that look.

Also confirm in the code: sns.set_theme(font_scale=1.0, style="whitegrid", font="DejaVu Sans"), sns.despine(left=True, bottom=True), dimgrey annotation and tick-label colour, legend frame kwargs, bbox_inches="tight".

6. Look

Read the PNG. First list what you see — title, axis labels, legend entries, annotations, marks — then judge:

  1. Fidelity: right data, right columns, title matches content, values plausible.
  2. Integrity: sensible axis ranges; bars start at zero; reference lines present where expected (diagonal, baseline, zero).
  3. Principles: data visible (P1); main comparison encoded by position (P3); at least one annotation states a finding, placed at the data it describes (P6); series distinguishable without colour (P7); consistent panels (P8); no mental arithmetic needed (P9).
  4. Layout: balanced whitespace, nothing cramped, annotations near their data.
  5. Pattern rules: the pattern's Signature is present.

Fix, re-run the script and the checker, and look again. Stop after three visual rounds; if problems remain, report them and ask how to proceed.

7. Report

If the user asked for publication quality, re-render at 300 DPI. Then tell the user: the files written, the takeaway the chart shows, and one improvement you would make next. Offer refinements.