Figure prep
GitHub用于在Oleafly手稿中构建和插入出版级图表,支持TikZ、pgfplots、CeTZ、matplotlib等多种工具,涵盖数据可视化、架构图及科学示意图的生成与排版。
Trigger Scenarios
Install
npx skills add Oleafly/Oleafly --skill Figure prep -g -y
SKILL.md
Frontmatter
{
"name": "Figure prep",
"license": "MIT",
"metadata": {
"oleafly": {
"tier": "native",
"phase": "figures",
"tools": [
"preview_figure",
"insert_figure",
"load_image",
"read_file",
"write_file",
"create_file",
"replace_in_file",
"compile",
"get_log",
"verify_pdf_pages",
"run_command",
"project_map",
"load_skill",
"read_skill_file"
]
},
"version": "1.1.1",
"skill-author": "Oleafly"
},
"description": "Build and place publication-quality figures in an Oleafly manuscript. Use when the user wants a TikZ or pgfplots figure, a CeTZ or fletcher figure in Typst, a diagram, an architecture or pipeline drawing, a matplotlib or seaborn plot, a chart from a CSV, a multi-panel figure, subfigures, a colorblind-safe palette, correct figure sizing for a journal column, or help with captions, labels, includegraphics and cross-references.",
"allowed-tools": "read_file write_file create_file replace_in_file list_files search_project project_map compile get_log get_pdf_text verify_pdf_pages run_command preview_figure insert_figure load_image update_todos load_skill read_skill_file",
"compatibility": "Figure preview works in LaTeX projects on Tectonic or latexmk and in Typst projects. Markdown projects have no figure preview. Matplotlib work needs Python 3.11 or newer on PATH and runs through approval-gated shell commands."
}
Figure prep
Figures carry the result. Get the encoding honest first, the layout second, and the caption last.
1. Decide what kind of figure this is
| The figure shows | Build it with | Route |
|---|---|---|
| Data: measurements, distributions, curves, comparisons | matplotlib or seaborn, exported to PDF | Section 4 |
| Structure: an architecture, a pipeline, a state machine, a proof sketch | TikZ, or pgfplots for data drawn in LaTeX. CeTZ or fletcher in Typst | Section 3 |
| A concept with no underlying data | TikZ or CeTZ if it can be drawn precisely, otherwise hand off to scientific-schematics | Section 6 |
| Something the user sketched or screenshotted | load_image to look at it, then redraw it |
Section 3 |
Before drawing anything, load_skill with id scientific-visualization and read references/publication_guidelines.md. Its non-negotiables apply here in full: never alter or hide data to improve a figure, keep bar baselines at zero, name what an error bar actually is, distinguish missing from zero, and never claim a palette or a DPI number makes a figure accessible.
2. Check which figure tools the run has
The figure tools come with the ordinary chat run, next to the file and compile tools. Which ones are there depends on the engine.
| Engine | preview_figure renders |
insert_figure wraps the code in |
load_image |
|---|---|---|---|
| Tectonic, latexmk | a TikZ picture in a small standalone LaTeX document | \begin{figure}[htbp] ... \end{figure} |
yes |
| Typst | Typst markup, such as a CeTZ canvas or a fletcher diagram | #figure(caption: [...])[ ... ] <label> |
yes |
| Markdown | not available | not available | yes |
When preview_figure is missing, say why in one line (a Markdown project, or an engine that has not loaded yet) and build the figure as a file instead.
3. TikZ
references/tikz-recipes.md in this skill has Tectonic-safe starting points for boxes and arrows, grouping, pgfplots, colors, and sizing, plus what the isolated preview does and does not share with the manuscript.
With preview_figure
preview_figurewithcode(the\begin{tikzpicture}...\end{tikzpicture}body), pluspackagesandlibrariesit needs.tikzis always included; name libraries explicitly, for examplearrows.meta,positioning,fit,calc,backgrounds,patterns.- Read
success,errorsandlog_tail. On failure, fix and call again. - The rendered page is handed to the model when the model can see images, so iterate on what it actually looks like: overlapping labels, arrows landing on the wrong anchor, a node wider than its box.
insert_figurewith the finalcode, acaptionand alabel. It wraps the code in\begin{figure}[htbp]\centering ... \end{figure}at the user's cursor and saves a PNG copy underfigures/<slug>.png.
Two things to know about insert_figure:
- The document ends up holding the TikZ source inline, not an
\includegraphics. The PNG underfigures/is a reference copy, not what the PDF uses. - It inserts
[htbp]. Papers usually want[t]. Fix that afterwards withreplace_in_file.
As a file
write_filethe figure tofigures/<name>.texcontaining just thetikzpicture.\input{figures/<name>}inside afigureenvironment in the section that discusses it.compile, thenverify_pdf_pageson the page that holds it to see the result.
This is the only drawing route on Markdown projects.
In a Typst project
Draw with CeTZ for diagrams and plots (cetz-plot for data plots), fletcher for node and arrow diagrams, or plain Typst (rect, grid, stack) for simple layouts.
-
preview_figurewithcodeas Typst markup. Put the imports it needs at the top, each with an exact version:#import "@preview/cetz:0.4.2" #cetz.canvas({ import cetz.draw: * rect((0, 0), (2, 1), name: "enc") content("enc", [Encoder]) rect((3, 0), (5, 1), name: "dec") content("dec", [Decoder]) line("enc.east", "dec.west", mark: (end: ">")) })packagesandlibrariesare for LaTeX and are ignored here. The figure renders alone on a white page, so it cannot read project files such as images or data. Put small data inline, or place a finished image withimage(...)in the manuscript instead. -
Read
success,errorsandwarnings. Line numbers count from the first line of your code. The first use of a package version downloads it, so that preview needs network. -
Iterate on the rendered image the same way as for TikZ.
-
insert_figurewith the finalcode, acaptionand alabelsuch asfig:pipeline. It moves the leading#importlines above the figure and skips any the document already has, wraps the rest in#figure(caption: [...])[ ... ], puts<fig:pipeline>after it, and saves a PNG copy underfigures/. Refer to it with@fig:pipeline.
4. Matplotlib
Scripts live in the project so the figure is reproducible.
create_fileascripts/folder andfigures/if they do not exist.write_filescripts/figure_<name>.py. Keep the data path, the transformations and the seed inside the script.run_commandwithpython3 scripts/figure_<name>.py. This asks the user for approval, runs in the project directory, has a 120 second budget, and inherits the login shell environment. There is no sandbox, so keep the script to reading its input and writing its output.- Export PDF into
figures/. Vector text stays sharp and searchable at any size. In a Typst project, SVG works on every version and PDF works from Typst 0.14 on, so checktypst.versioninproject.jsonbefore you pick PDF. read_skill_filescientific-visualizationfor depth:references/journal_requirements.mdfor sizes and formats,references/color_palettes.mdfor palettes,assets/publication.mplstyleandassets/presentation.mplstylefor style sheets,assets/color_palettes.pyandscripts/style_presets.pyfor the presets,scripts/figure_export.pyfor an exporter that refuses silent overwrites and records provenance.
Those scripts sit in the skill directory, not the project. load_skill returns the absolute directory, so run one as python3 "<skill dir>/scripts/style_presets.py", or copy the parts you need into the project script. They need Python 3.11 or newer.
references/matplotlib-route.md in this skill has the concrete shape of a figure script, the sizing table, and what to do when Python is missing.
5. Wire it into the manuscript
\begin{figure}[t]
\centering
\includegraphics[width=\linewidth]{figures/architecture.pdf}
\caption{System architecture. The encoder on the left feeds the fusion module.}
\label{fig:architecture}
\end{figure}
Rules that are not negotiable:
width=\linewidth, or a fraction of it. Not\textwidthinside a two-column layout.- Caption below a figure, above a table.
\labelafter\caption, never before, or every reference points at the enclosing section. - Refer with
\cref{fig:architecture}from cleveref, which writes the word for you. With plain\ref, put a~in front:Figure~\ref{fig:architecture}. [t]is the right default for papers.[h]alone is ignored by LaTeX.[H]from thefloatpackage forces placement and breaks page flow, so keep it for reports.- Every figure is referenced from the text at least once.
project_mapreports labels; check nothing is orphaned. - Full-width figure in a two-column layout:
figure*. - Subfigures come from
subcaption. Never loadsubfigureorsubfig.
In a Typst project the same figure looks like this:
#figure(
image("figures/architecture.svg", width: 100%),
caption: [System architecture. The encoder on the left feeds the fusion module.],
placement: top,
) <fig:architecture>
- Refer with
@fig:architecture, which prints the supplement and number for you. - The label goes after the closing parenthesis, outside the call.
placement: topfloats the figure like[t]does. Leave it out to keep the figure where it is in the text.- Typst puts every caption below by default. For tables above, add
#show figure.where(kind: table): set figure.caption(position: top)once near the top of the document. - Full width in a two-column layout:
placement: topwithscope: "parent".
Captions carry the claim. First sentence says what the figure shows, the rest says what to notice. A caption that only names the axes is wasted.
6. Hand off
- Conceptual diagrams that resist precise drawing: scientific-schematics. Read its
references/best_practices.mdandreferences/iterative_refinement.md. Its image-generation scripts are deliberately not bundled with Oleafly, because they call an external image service and read.envfiles from parent directories, so treat that skill as guidance and draw the figure here. - Figure design theory, palettes, journal export rules: scientific-visualization.
- Compile failures anywhere in this loop: oleafly-latex-build.
- Figures for a deck or a poster: oleafly-slides-and-posters.
Publication quality checklist
- The encoding is honest: zero baselines for bars, no truncated axis that manufactures an effect, missing data shown as missing
- Uncertainty is named in the caption, with
nand the unit of replication - Color is never the only cue. Every series also differs by marker, line style, hatch, or a direct label
- The palette survives grayscale and common color-vision deficiencies. Okabe-Ito is a safe default
- Font size at final printed size is close to the body text, roughly 7 to 9 pt for most journals. Set the figure's physical width, do not scale it in
\includegraphics - Vector (PDF) for plots and diagrams. Raster only for photographs and screenshots, at 300 dpi or better. Never JPEG for a plot
- Axis labels carry units. Tick labels are not scientific notation soup
- The figure is referenced from the text and the reference reads correctly in the PDF
- The caption states the claim, not just the contents
- It was looked at in the compiled PDF at final size, with
verify_pdf_pageswhere available
Failure handling
| Problem | What to do |
|---|---|
preview_figure is not available |
The project is Markdown, or the engine has not loaded yet. Build the figure as a file |
| A Typst preview fails inside a package file | The package version does not match the project's Typst version. Pick a package version made for it, and do not change the pin yourself |
insert_figure returns declined |
The user rejected the approval card. Ask what to change rather than re-sending the same figure |
| A TikZ library is missing from the bundle | Name it. Tectonic cannot install packages; offer the closest bundled alternative |
python3 is not found |
Say so and offer the TikZ, pgfplots, or CeTZ route instead. Do not install anything |
| The script needs a package that is not installed | Ask before installing. run_command inherits the user's environment and has no sandbox |
| The figure looks right in preview but wrong in the document | Column width. Re-check with the real \linewidth and verify_pdf_pages |
run_command times out |
The 120 second budget was exceeded. Split the work or cache the intermediate data |
Artifacts
figures/*.pdf or figures/*.png, scripts/figure_*.py where Python was used, the figure environment in the manuscript, and a compiled PDF that shows the figure in place.
Done when
- The figure compiles as part of the whole document, not only in isolation
- It is referenced from the text and the cross-reference resolves
- The caption and label are present, in the right order
- The checklist above was worked through, and anything skipped was named
- The source that produces it (TikZ or Typst code, or a Python script) is in the project
From a terminal
Outside the app (a terminal, or a coding agent with a shell), the oleafly command does the same work. Always pass --json and check ok.
| In Oleafly | From a terminal |
|---|---|
compile |
oleafly build --json |
get_log |
oleafly log --diagnostics --json |
project_map |
oleafly context --json |
list_files, read_file, search_project |
Your own file tools; oleafly context --json for the outline |
Version History
- afd83e2 Current 2026-11-02 08:54


