MATLAB Plot Skill
Overview
Use this skill to fix messy MATLAB figures and turn rough plots into publication-quality output. The workflow is: read the plotting code and destination document, refactor the figure, export a vector PDF plus a PNG preview, read the rendered PNG yourself, critique it, and iterate until the result is clearly professional.
The non-negotiable idea: do not stop after writing plotting code. Code that looks correct is not the same as a figure that looks correct — you must generate, export, look, and iterate.
When To Use It
- MATLAB
.m files that create or export figures.
- Figures that look cramped, blurry, inconsistent, or amateurish.
- Multi-panel paper figures where spacing, legends, titles, and page fit matter.
- Overleaf or LaTeX workflows that need vector PDF output.
- Requests like
publication-quality, journal-ready, clean up this figure, make this plot readable, or anything that effectively means "this MATLAB figure looks messy."
Non-Negotiable Review Loop
Do not stop after writing plotting code.
- Read the plotting script and the destination file (
.tex, .md, slide deck) that will include the figure. Decide the figure's final printed width first: look in the .tex for \columnwidth (single column, 3.3 in) vs \textwidth (6.5 in), and size fonts for that width.
- Generate the figure by running MATLAB headlessly, and lint any script you write:
matlab -batch "checkcode('make_figure.m'); run('make_figure.m')"
-batch runs without a desktop, exits when finished, and returns a nonzero exit code on error; checkcode surfaces syntax/usage warnings to fix before you trust the run.
- Export a vector PDF for the paper and a raster PNG preview:
exportgraphics(fig, 'figure.pdf', 'ContentType', 'vector'); % deliverable
exportgraphics(fig, 'figure.png', 'Resolution', 220); % what you read
(Or pass PreviewPath to scripts/export_publication_figure.m to get both at once.)
- Read the PNG with your image-reading tool. You cannot visually inspect a vector PDF directly, so the PNG preview is the read target — the PDF is the deliverable. If only a PDF exists, rasterize page 1 first (
pdftoppm -png -r 200 -singlefile figure.pdf out or magick -density 200 figure.pdf out.png, both producing out.png).
- If you can compile the document, render the embedded page and read it too. This step is conditional — never skip step 4 because step 5 is impossible.
- Critique the rendered PNG against
references/render_review_checklist.md: aspect ratio, whitespace, title readability, legend placement, font sizes, clipping, marker visibility, line weights, panel balance, and page fit.
- Iterate on the MATLAB code and repeat the export until the figure is clearly professional.
If MATLAB is not available, do not claim the figure was rendered or reviewed. Deliver the refactored .m code, state plainly that it was not executed or visually verified, and give the user the exact matlab -batch command to run plus what to check. The same honesty applies whenever you cannot read the rendered figure for any reason.
Worked Recipe
The full loop in one place — build, export both files, then read the PNG:
addpath('<skill>/scripts'); % e.g. ~/.claude/skills/matlab-plot-skill/scripts
fig = figure;
tl = tiledlayout(fig, 2, 2, 'TileSpacing', 'compact', 'Padding', 'compact');
nexttile; plot(x, y1); title('Panel A');
nexttile; plot(x, y2); title('Panel B');
% ... remaining panels, one shared legend ...
export_publication_figure(fig, 'out/figure.pdf', ...
WidthInches=6.5, PreviewPath='out/figure.png');
Then read out/figure.png and iterate. (If you would rather not depend on the helper, the two exportgraphics lines in step 3 do the same export inline.)
Common Defects → Fix
Look for these in the rendered PNG; read references/matlab_figure_guidelines.md for the full rules and rationale before styling.
- Cramped panels → increase canvas height before shrinking fonts.
- Tiny text after
\columnwidth scaling → export at the final width so LaTeX needs no scaling.
- Legend stealing plot area → one shared legend docked outside the tiles (
lgd.Layout.Tile = 'south').
- Thin lines / small markers after scaling → raise line width and marker size.
- Crowded or rainbow colors → one concept per color, colorblind-safe palette;
parula/viridis (not jet) for continuous data.
- Crowded ticks or a corner
1e4 multiplier → sparse explicit ticks; ax.YAxis.Exponent = 0.
- Clipped titles or labels → loosen
TileSpacing/Padding.
Decisions
- Refactor an existing
.m in place: preserve the data and computation, change only styling and layout.
- Move
subplot to tiledlayout unless rewriting would risk the user's intent on code they want minimally touched.
- Default to vector PDF; rasterize (
exportgraphics(ax, ..., 'ContentType', 'image') at 300–600 DPI) only when one layer has many thousands of primitives and the vector PDF becomes huge or slow to compile.
Helper
scripts/export_publication_figure.m applies explicit sizing, readable defaults, and the vector-PDF + PNG-preview export. Copy it into the project, or add its folder to the MATLAB path (addpath('<skill>/scripts')) before calling it, as in the recipe above.
Report Back
- State what changed in the MATLAB code.
- Cite the exact PNG path you read and at least one concrete thing you observed and acted on (e.g. "legend overlapped Panel B, moved it outside"). If you could not render or read it, say so and state what remains unverified.
- Mention any remaining limitations, warnings, or assumptions.
Resources
1---2name: matlab-plot-skill3description: Use this skill when MATLAB figures look messy: cramped subplots, unreadable titles, awkward legends, bad page fit, or broken PDF output for LaTeX or Overleaf. It turns rough MATLAB plots into publication-quality figures by exporting the figure, reading the rendered figure, and iterating on the layout until it looks clean.4---56# MATLAB Plot Skill78## Overview910Use this skill to fix messy MATLAB figures and turn rough plots into publication-quality output. The workflow is: read the plotting code and destination document, refactor the figure, export a vector PDF plus a PNG preview, **read the rendered PNG yourself**, critique it, and iterate until the result is clearly professional.1112The non-negotiable idea: do not stop after writing plotting code. Code that looks correct is not the same as a figure that looks correct — you must generate, export, look, and iterate.1314## When To Use It1516- MATLAB `.m` files that create or export figures.17- Figures that look cramped, blurry, inconsistent, or amateurish.18- Multi-panel paper figures where spacing, legends, titles, and page fit matter.19- Overleaf or LaTeX workflows that need vector PDF output.20- Requests like `publication-quality`, `journal-ready`, `clean up this figure`, `make this plot readable`, or anything that effectively means "this MATLAB figure looks messy."2122## Non-Negotiable Review Loop2324Do not stop after writing plotting code.25261. **Read** the plotting script and the destination file (`.tex`, `.md`, slide deck) that will include the figure. Decide the figure's final printed width first: look in the `.tex` for `\columnwidth` (single column, ~3.3 in) vs `\textwidth` (~6.5 in), and size fonts for that width.272. **Generate** the figure by running MATLAB headlessly, and lint any script you write:28 ```bash29 matlab -batch "checkcode('make_figure.m'); run('make_figure.m')"30 ```31 `-batch` runs without a desktop, exits when finished, and returns a nonzero exit code on error; `checkcode` surfaces syntax/usage warnings to fix before you trust the run.323. **Export** a vector PDF for the paper and a raster PNG preview:33 ```matlab34 exportgraphics(fig, 'figure.pdf', 'ContentType', 'vector'); % deliverable35 exportgraphics(fig, 'figure.png', 'Resolution', 220); % what you read36 ```37 (Or pass `PreviewPath` to `scripts/export_publication_figure.m` to get both at once.)384. **Read the PNG** with your image-reading tool. You cannot visually inspect a vector PDF directly, so the PNG preview is the read target — the PDF is the deliverable. If only a PDF exists, rasterize page 1 first (`pdftoppm -png -r 200 -singlefile figure.pdf out` or `magick -density 200 figure.pdf out.png`, both producing `out.png`).395. If you can compile the document, render the embedded page and read it too. This step is conditional — never skip step 4 because step 5 is impossible.406. **Critique** the rendered PNG against [`references/render_review_checklist.md`](./references/render_review_checklist.md): aspect ratio, whitespace, title readability, legend placement, font sizes, clipping, marker visibility, line weights, panel balance, and page fit.417. **Iterate** on the MATLAB code and repeat the export until the figure is clearly professional.4243**If MATLAB is not available**, do not claim the figure was rendered or reviewed. Deliver the refactored `.m` code, state plainly that it was not executed or visually verified, and give the user the exact `matlab -batch` command to run plus what to check. The same honesty applies whenever you cannot read the rendered figure for any reason.4445## Worked Recipe4647The full loop in one place — build, export both files, then read the PNG:4849```matlab50addpath('<skill>/scripts'); % e.g. ~/.claude/skills/matlab-plot-skill/scripts5152fig = figure;53tl = tiledlayout(fig, 2, 2, 'TileSpacing', 'compact', 'Padding', 'compact');54nexttile; plot(x, y1); title('Panel A');55nexttile; plot(x, y2); title('Panel B');56% ... remaining panels, one shared legend ...5758export_publication_figure(fig, 'out/figure.pdf', ...59 WidthInches=6.5, PreviewPath='out/figure.png');60```6162Then **read `out/figure.png`** and iterate. (If you would rather not depend on the helper, the two `exportgraphics` lines in step 3 do the same export inline.)6364## Common Defects → Fix6566Look for these in the rendered PNG; read [`references/matlab_figure_guidelines.md`](./references/matlab_figure_guidelines.md) for the full rules and rationale before styling.6768- Cramped panels → increase canvas height before shrinking fonts.69- Tiny text after `\columnwidth` scaling → export at the final width so LaTeX needs no scaling.70- Legend stealing plot area → one shared legend docked outside the tiles (`lgd.Layout.Tile = 'south'`).71- Thin lines / small markers after scaling → raise line width and marker size.72- Crowded or rainbow colors → one concept per color, colorblind-safe palette; `parula`/`viridis` (not `jet`) for continuous data.73- Crowded ticks or a corner `1e4` multiplier → sparse explicit ticks; `ax.YAxis.Exponent = 0`.74- Clipped titles or labels → loosen `TileSpacing`/`Padding`.7576## Decisions7778- Refactor an existing `.m` in place: preserve the data and computation, change only styling and layout.79- Move `subplot` to `tiledlayout` unless rewriting would risk the user's intent on code they want minimally touched.80- Default to vector PDF; rasterize (`exportgraphics(ax, ..., 'ContentType', 'image')` at 300–600 DPI) only when one layer has many thousands of primitives and the vector PDF becomes huge or slow to compile.8182## Helper8384[`scripts/export_publication_figure.m`](./scripts/export_publication_figure.m) applies explicit sizing, readable defaults, and the vector-PDF + PNG-preview export. Copy it into the project, or add its folder to the MATLAB path (`addpath('<skill>/scripts')`) before calling it, as in the recipe above.8586## Report Back8788- State what changed in the MATLAB code.89- Cite the exact PNG path you read and at least one concrete thing you observed and acted on (e.g. "legend overlapped Panel B, moved it outside"). If you could not render or read it, say so and state what remains unverified.90- Mention any remaining limitations, warnings, or assumptions.9192## Resources9394- [`scripts/export_publication_figure.m`](./scripts/export_publication_figure.m): reusable export helper for publication-style figures.95- [`references/matlab_figure_guidelines.md`](./references/matlab_figure_guidelines.md): structural, color, sizing, and layout conventions — read before styling.96- [`references/render_review_checklist.md`](./references/render_review_checklist.md): the post-export visual checklist — work through it before declaring the figure done.