Skip to content
Back to skills

Research Figures

ASecurity

Produce publication-grade figures for a thesis or paper from result data: matplotlib with a consistent, colour-blind-safe style file, vector output sized to the text width, one figure per claim, variance shown, direct labels over legends, and captions that carry the argument; plus TikZ for architecture and method diagrams. Use when a results section needs figures, when a supervisor calls a plot unreadable, or when the document's figures do not match each other.

  • 5 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
ai-agentspythongonodegit

Security analysis

A100/100

Scanned September 24, 2026

npx -y skills add KhaledSaeed18/dotclaude --skill research-figures --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Research Figures?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Research Figures
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/khaledsaeed18-research-figures/badge)](https://www.skillsdirectory.com/skills/khaledsaeed18-research-figures)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: research-figures
description: "Produce publication-grade figures for a thesis or paper from result data: matplotlib with a consistent, colour-blind-safe style file, vector output sized to the text width, one figure per claim, variance shown, direct labels over legends, and captions that carry the argument; plus TikZ for architecture and method diagrams. Use when a results section needs figures, when a supervisor calls a plot unreadable, or when the document's figures do not match each other."
argument-hint: "(optional) the data file or script, the claim the figure supports, and the target width"
---

A figure earns its place by making one claim visible faster than the table does. Design from the claim, not from the data: decide what the reader must see, then choose the encoding that shows it.

## Rules that apply to every figure

- **One claim per figure.** If the caption needs "and also", split it.
- **Vector output** (`.pdf` for LaTeX, `.svg` or 300-dpi `.png` for Word) at the final printed size, so fonts are not scaled. Text width in a typical thesis is about 6 inches (15 cm); set `figsize` accordingly and never rescale in the document.
- **Fonts match the document**: same family (or the closest available) and a size between the caption size and the body size (9 to 11 pt at print size). Set once in the style file.
- **Colour-blind-safe palette** (Okabe-Ito or viridis for sequential data). Never encode a difference by colour alone: vary marker or line style too, and check the figure in greyscale.
- **Show variance**: error bars, confidence bands, or individual points. State in the caption what the bar is (SD, SEM, 95% CI) and n.
- **Direct labels** at line ends beat legends when there are fewer than six series.
- **Axes** start at zero for bar charts; for line charts, start where the data live and say so. Label with quantity and unit. Log scale when the data span orders of magnitude, stated in the label.
- **No chartjunk**: no 3D, no gradients, no gridlines heavier than the data, no titles inside the figure (the caption is the title).
- **Consistency**: the same variable has the same colour in every figure of the thesis. Keep a `colors` dict in the style module.
- **Reproducible**: every figure comes from a script in `figures/src/` that reads the data file and writes the output. No hand-edited figures.

## Setup

`figures/src/style.py`:

```python
import matplotlib as mpl
import matplotlib.pyplot as plt

OKABE_ITO = ["#0072B2", "#E69F00", "#009E73", "#D55E00", "#CC79A7", "#56B4E9", "#F0E442", "#000000"]
COLORS = {"baseline": OKABE_ITO[0], "ours": OKABE_ITO[3]}   # one entry per named series, thesis-wide

def use_thesis_style(text_width_in=6.0, ratio=0.6):
    mpl.rcParams.update({
        "figure.figsize": (text_width_in, text_width_in * ratio),
        "font.family": "serif", "font.size": 10,
        "axes.labelsize": 10, "axes.titlesize": 10,
        "xtick.labelsize": 9, "ytick.labelsize": 9, "legend.fontsize": 9,
        "axes.prop_cycle": mpl.cycler(color=OKABE_ITO),
        "axes.spines.top": False, "axes.spines.right": False,
        "axes.grid": True, "grid.alpha": 0.3, "grid.linewidth": 0.5,
        "lines.linewidth": 1.5, "lines.markersize": 4,
        "errorbar.capsize": 2,
        "savefig.bbox": "tight", "savefig.pad_inches": 0.02,
        "pdf.fonttype": 42, "ps.fonttype": 42,        # embed TrueType, editable text
        "text.usetex": False,                          # True if the LaTeX toolchain is present
    })
```

A figure script:

```python
import pandas as pd, matplotlib.pyplot as plt
from style import use_thesis_style, COLORS
use_thesis_style()
df = pd.read_csv("../../results/latency.csv")
fig, ax = plt.subplots()
for name, g in df.groupby("system"):
    m, s = g.groupby("n")["ms"].mean(), g.groupby("n")["ms"].std()
    ax.plot(m.index, m, marker="o", color=COLORS[name], label=name)
    ax.fill_between(m.index, m - s, m + s, color=COLORS[name], alpha=0.2)
    ax.annotate(name, (m.index[-1], m.iloc[-1]), xytext=(4, 0), textcoords="offset points", va="center", color=COLORS[name])
ax.set_xlabel("Input size (items)"); ax.set_ylabel("Latency (ms)"); ax.set_xscale("log")
fig.savefig("../latency.pdf")
```

## Choosing the encoding

| To show | Use | Avoid |
| --- | --- | --- |
| a trend over an ordered variable | line with band | bars |
| comparison of a few categories | dot plot or horizontal bars, sorted | pie, stacked bars with many parts |
| distribution | box plot with points, violin, or ECDF | bar of the mean alone |
| relationship between two measures | scatter with a fitted line and its CI | connected scatter |
| composition | stacked bar only with two or three parts; otherwise a table | 3D anything |
| many small comparisons | small multiples with shared axes | one crowded plot |
| an architecture or pipeline | TikZ or a drawing tool exported to PDF, consistent box and arrow styles | screenshots of slides |

## Captions

Caption = what is shown + conditions + what to notice. "Latency by input size for the baseline and the proposed system (mean of 10 runs, shaded band is one SD, log x-axis). The proposed system's advantage grows with input size, reaching 4x at 10^5 items." The reader should get the claim from the caption without the body text.

## Diagrams

For system and method diagrams use TikZ (`tikzpicture` with `positioning` and `arrows.meta` libraries, one shared style block for nodes) so fonts and line weights match the document. Keep each diagram in its own `.tex` file under `figures/`, `\input` it, and compile standalone with the `standalone` class to preview. Export to PDF for Word.

## Before including

Print the figure at final size in greyscale. If a series cannot be told apart, or a label is under 8 pt, fix it. Check every figure is referenced in the text before it appears.

## Attribution

Palette and rcParams conventions draw on [thesis-figure-skill](https://github.com/0xe1337/thesis-figure-skill) (MIT) and the Okabe-Ito palette; the encoding table and rules are this repository's.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.