# scipilot-figure-skill names SciencePlots as a foundation and comments it out of requirements.txt

> scipilot-figure-skill is a Claude Code skill that profiles a dataset before choosing a chart for it, renders to journal specifications, then audits its own output both in code and by reading the image back. Its README is bilingual and the Chinese half is the more detailed one, its dependency file comments out SciencePlots even though the introduction lists it as one of the three things the skill is built on, and the version it claims has no release behind it.

**Haojae/scipilot-figure-skill** — SciPilot Skills family - Publication-grade scientific figure copilot for Claude Code 

- Repository: https://github.com/Haojae/scipilot-figure-skill
- Stars: 2,536 · Forks: 87
- Language: Python
- License: MIT
- Published: 2026-09-17 · Updated: 2026-09-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/haojae-scipilot-figure-skill

## SciencePlots is named as a foundation and commented out of the dependency file

The introduction says the skill is built on matplotlib, seaborn and SciencePlots for static output, and on plotly for interactive output. The dependency file does not install one of those three:

```
matplotlib>=3.7
seaborn>=0.13
plotly>=5.18
Pillow>=10.0
numpy>=1.24
pandas>=2.0
scipy>=1.10

# Optional enhancements (skill degrades gracefully if missing)
# SciencePlots>=2.1
# pypdf>=4.0
# kaleido>=0.2.1
# PyMuPDF>=1.23      # only for visual_qa.render_preview() of already-saved PDFs
```

Seven lines are active and four are commented out. SciencePlots sits in the commented group, under a note that the skill degrades gracefully if the optional packages are missing. The README repeats that framing in prose, calling SciencePlots, pypdf and kaleido optional enhancements whose absence does not affect running.

That is coherent as a policy. It sits awkwardly with the introduction, which lists the library as one of three foundations rather than as an optional extra. Step four of the workflow, the style step, is described as applying a journal preset, and a journal preset is what a styling library of that kind is for.

The PyMuPDF comment is the most precisely scoped line in the file: it exists only for the preview renderer that audits PDFs that have already been saved.

## The English workflow drops the export step the Chinese one spells out

The eight-step workflow appears twice, once per language, and the two versions do not carry the same detail. The English one reads:

```
0. Understand   — what does this figure argue? where is the data?
   ↓
1. Profile      — profile_data.py: types / n / distribution / outliers / corr
   ↓
2. Select       — chart_selection.md: decision framework by shape + intent
   ↓ (active interception → viz_pitfalls.md)
3. Spec         — journal_specs.md: column width / font / DPI
   ↓
4. Style        — setup_style.py: journal preset + CJK font config
   ↓
5. Plot         — plot_recipes.md: 9 recipe families
   ↓
6. Self-check   — visual_qa (program) + AI reads the PNG (visual_review.md): glyphs/clipping/overlap/alignment
   ↓
7. Export
```

The Chinese version numbers the same eight steps from 0 to 7 and attaches a file to each one. Its last step names export_figure.py and describes what it does: multiple formats, output at the final size, and a grayscale preview. The English step 7 is the bare words Export, with no script and no description.

So the reader working in English loses the name of the export script and loses the grayscale preview from the step list entirely, even though the grayscale check appears again later in the hard principles.

This is the general shape of the README. The Chinese half is the longer and more specific document, and the English half is the one that stops early.

## The pitfall list shows nine of fifteen and prints them out of order

The interception rules are numbered P1, P2, and so on. The README says the full set of fifteen lives in a reference file and shows a selection. Nine are shown, and the selection is not in numeric order.

The order on the page runs P1, P2, P3, P4, P6, then P14, then P12, then P16, then P18. P14 arrives before P12, so the list is neither a prefix of the numbering nor sorted.

The rules themselves are concrete. P1 rejects a mean bar for a group with fewer than ten samples, on the grounds that the bar hides the distribution, and substitutes a box plot with a strip plot. P2 rejects dual y-axes because the apparent correlation is produced by the plotting choice rather than the data, and proposes splitting into subplots or standardising. P3 replaces pie charts and 3D charts with horizontal bars. P4 requires a y-axis to start at zero or to show its break. P6 rejects a line joining means across a categorical x, and P14 replaces rainbow and jet colour maps with viridis and RdBu_r. P12 is one argument per figure. P16 sends Chinese text and minus signs that render as boxes back through the style setup. P18 routes misplaced panel letters through the panel-label helper.

Nine shown out of fifteen leaves six identifiers unaccounted for on the page: P5, P7 through P11, P13, P15 and P17.

## The version is asserted in the README with no release behind it

The family table marks this repository as version 2.1.0, and a section heading announces what arrived in 2.1, namely the post-render visual self-check loop. A section near the bottom of the repository file list also carries the same number in its copyright line, dated 2026.

None of that has a release attached. The repository has no GitHub releases at all, so there is no tag stream behind the 2.1.0 claim and nothing to compare it against.

The install instructions make the consequence concrete. The manual route clones the repository and installs its requirements:

```
git clone https://github.com/Haojae/scipilot-figure-skill.git \
          ~/.claude/skills/scipilot-figure-skill
pip install -r ~/.claude/skills/scipilot-figure-skill/requirements.txt
```

A clone takes the default branch tip. There is no tag to check out, so a reader who wants exactly what the README describes as version 2.1.0 has nothing to pin to and ends up with whatever the branch held at the moment they ran the command.

The recorded last push is dated 2026-06-15, months after the 2026 copyright line was written and well before the version claim could be checked against anything.

## Installation is a sentence to paste, not a command to run

The primary install method is not a shell command. It is a prompt, written in Chinese and pointed at the agent itself:

```
请帮我安装这个 Skill：https://github.com/Haojae/scipilot-figure-skill.git
```

That line, pasted into Claude Code, is the documented path. The git clone and pip install above it are labelled the manual alternative.

So the project expects the agent to perform its own installation, and the clone target confirms where the result is expected to land: `~/.claude/skills/scipilot-figure-skill`, a user-level skill directory rather than anything inside a project. A per-project or per-team install is not described.

The skill format itself is visible in the tree. A `SKILL.md` sits at the repository root as the definition the agent reads, with a `references/` directory holding the decision framework, the journal specifications, the plot recipes, the pitfall list and the visual review notes, and a `scripts/` directory holding the Python the agent invokes.

The family table frames the project as the second member of a set, alongside a citation skill and a writing skill at version 1.0.0, with three further members listed as planned rather than built.

## Self-checking runs twice, once in code and once by reading the image

The addition in version 2.1 is a loop that runs after rendering rather than only before it. The stated problem is that a generic plotter stops at saved, so Chinese glyph boxes, clipped labels, legends sitting on top of data and misaligned panel letters all survive to submission.

The loop has two halves, and they divide by what each can detect. The programmatic half is an audit call that watches both the warning channel and the logging channel, so missing-glyph reports are caught whichever one matplotlib uses, and it checks for text running outside its bounds and for overlapping tick labels. The other half has the agent read the rendered PNG with vision and judge what code cannot: whether a legend covers the data, whether the panel letters line up, and whether the colours stay distinguishable in grayscale.

Two supporting pieces sit alongside. One helper places panel labels using shared figure coordinates so a, b, c and d line up horizontally and vertically instead of being positioned by hand. The other is in the style setup, which by default corrects the minus-sign box problem and configures a CJK font across all modes.

Notably, these concrete names appear in the Chinese section only. The English self-check step refers to the audit and the visual review notes without naming the audit function or the label helper.

## Four scripts have documented commands and two named modules do not

The scripts can be run directly, and four of them are shown with their flags:

```
python scripts/profile_data.py results.csv --group group --group condition
python scripts/setup_style.py --list-fonts
python scripts/export_figure.py demo --out ./test_demo
python scripts/check_figure.py figs/*.pdf --min-dpi 300 --strict
```

The profiling script takes `--group` more than once, so grouping columns are declared by repetition rather than by a comma list. The style script has a listing mode for available CJK fonts. The export script is shown running a demo with an output path. The compliance checker is given a glob of PDF files, a minimum DPI of 300 and a strict flag.

That checker deserves a second look against the hard principles. The principles say to output at the final size with no secondary scaling, to prefer vector formats for data figures with PDF, SVG and EPS listed, to use TIFF or PNG only for photographs, and to refuse JPEG outright. The self-check input is PDFs with a DPI floor, which means the number being enforced is the resolution of raster content inside a file the rules otherwise push you to keep vector.

The workflow text also names a visual audit module and a layout helper module, and neither appears in this command list. The documented command surface is therefore smaller than the named module surface.

## The CJK font search is a fixed chain, and finding nothing raises

Chinese text rendering is handled by a single function with a language argument, and the font search is an ordered list rather than a scan:

```
Noto Sans CJK SC > Source Han Sans SC > SimHei > Microsoft YaHei
```

The first hit wins. That is a fixed preference order across four families, two of which are Linux-oriented, one commonly present on Windows, and one a Windows system font. Nothing in the list names macOS, where the equivalent families carry different names.

When none of the four is found, the stated behaviour is to raise with a clear installation prompt rather than continue. Given that the whole point of the setting is that Chinese must not render as boxes, failing loudly is the right default, and the fix is a font install the user has to perform themselves.

There is a second option for the mixed-typesetting case. Chinese journals commonly set Chinese characters in a Song face alongside Times New Roman for numerals, and a flag switches the serif face for Chinese text so those two can be mixed.

The style setup is also where the negative-sign box problem is corrected by default across all modes, which means the CJK work and the minus-sign work happen in the same place rather than being two separate repairs.

## Conclusion

This skill earns its place for anyone who has data and knows the argument but not the chart, because the profiling step and the interception rules attack exactly the failure the README names: knowing matplotlib and still picking the wrong figure. Two things to check before trusting it. SciencePlots is not installed by default, so the journal-style presets that step four of the workflow applies are the part a fresh install ends up missing, and the dependency file lists it as optional rather than required. And the version is asserted in the README with no release behind it, so the clone in the install instructions follows the default branch rather than a tag. The bilingual README is also lopsided: the Chinese half carries the concrete function names and the English half drops several of them, so read the Chinese if you want the audit internals. MIT covers the code.

## FAQ

### What does scipilot-figure-skill actually do?

It profiles your data first, asking what argument the figure is meant to make, then chooses a chart type from the data shape and that intent, then renders it to journal specifications. After rendering it audits the result both programmatically and by having the agent read the image back, then loops until it passes.

### How do I install scipilot-figure-skill?

The documented route is to ask the agent to install it, pasting the sentence 请帮我安装这个 Skill with the repository URL. The manual alternative is a git clone into ~/.claude/skills/scipilot-figure-skill followed by pip install -r on the requirements file. The clone follows the default branch, since the repository has no releases to pin.

### Which plotting libraries does scipilot-figure-skill require?

requirements.txt lists matplotlib, seaborn, plotly, Pillow, numpy, pandas and scipy as active dependencies. SciencePlots, pypdf, kaleido and PyMuPDF are all commented out as optional, even though the introduction names SciencePlots as one of the three libraries the skill is built on.

## Sources

- [Haojae/scipilot-figure-skill on GitHub](https://github.com/Haojae/scipilot-figure-skill)
- [Issues](https://github.com/Haojae/scipilot-figure-skill/issues)
- [License: MIT](https://github.com/Haojae/scipilot-figure-skill/blob/main/LICENSE)
- [README](https://github.com/Haojae/scipilot-figure-skill/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/haojae-scipilot-figure-skill
