Sci-Figure — Scientific Figure Extractor
Precisely extract figures and sub-figures from academic PDF papers.
License note: sci-figure is licensed under AGPL-3.0-or-later because it links PyMuPDF (fitz), which is AGPL-licensed.
Installation
Install the package from the skill directory before first use:
cd ${SKILL_DIR}
pip install -e .
This registers the sh-sci-fig CLI command. Requires Tesseract OCR:
- Windows:
winget install UB-Mannheim.TesseractOCR
- Linux:
apt install tesseract-ocr
- macOS:
brew install tesseract
Preferences (EXTEND.md)
Use Bash to check EXTEND.md existence (priority order):
# Check project-level first
test -f .baoyu-skills/sci-figure/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/sci-figure/EXTEND.md" && echo "user"
EXTEND.md Supports: Default DPI | Default output format | Tesseract path
Usage
sh-sci-fig <input.pdf> [options]
Options
| Option |
Short |
Description |
Default |
<input> |
|
PDF file path |
Required |
--figure |
-f |
Figure number (1, 2, 3...) |
Required (except --list/--all) |
--subfigure |
-s |
Sub-figure label (a, b, c...) |
None (returns whole figure) |
--output |
-o |
Output directory |
Current directory |
--dpi |
-d |
Output resolution |
600 |
--list |
-l |
List all available figure numbers |
false |
--all |
|
Extract all figures |
false |
--format |
|
Output format (png/jpg) |
png |
--strategy |
|
Extraction strategy: hybrid/native/cv |
hybrid |
--ocr |
|
OCR engine: tesseract/easyocr/none |
tesseract |
--render-page |
|
Render full page with annotations |
false |
--annotate |
|
Draw bounding boxes on rendered page |
false |
--bbox |
|
Manual bbox override (x0,y0,x1,y1 in px) |
None |
--no-trim |
|
Disable whitespace trimming |
false |
--debug |
|
Enable debug logging |
false |
--quiet |
-q |
Suppress info messages |
false |
Examples
# Extract Figure 2, sub-figure c
sh-sci-fig paper.pdf -f 2 -s c
# Extract entire Figure 3
sh-sci-fig paper.pdf -f 3
# List all available figures in a PDF
sh-sci-fig paper.pdf --list
# Extract all figures
sh-sci-fig paper.pdf --all
# Custom output directory and DPI
sh-sci-fig paper.pdf -f 2 -s c -o ./output/ -d 300
# Use EasyOCR for sub-figure label detection
sh-sci-fig paper.pdf --all --ocr easyocr
# CV-only strategy (skip native extraction)
sh-sci-fig paper.pdf --all --strategy cv
# Render page with annotated bounding boxes (debugging)
sh-sci-fig paper.pdf -f 1 --render-page --annotate
# Manual bbox extraction (multimodal correction)
sh-sci-fig paper.pdf -f 1 --bbox 100,200,800,1200
Output:
Extracted: figure_2c.png (1920x1080, 600 DPI)
Error Handling
| Scenario |
Behavior |
| Figure number not found |
Error + list all available figure numbers |
| OCR recognition failed |
Return entire figure region |
| Sub-figure split failed |
Return entire figure region |
| No sub-figure labels found |
Return entire figure region |
Tech Stack
| Library |
Role |
| pdfplumber |
Text + coordinate extraction (caption detection) |
| PyMuPDF (fitz) |
Native image extraction + high-quality page rendering |
| opencv-python |
CV region detection, connected-component analysis, content validation |
| Pillow |
Final cropping, format conversion |
| pytesseract |
OCR for sub-figure label recognition (default) |
| easyocr |
Alternative OCR engine (optional, pip install sci-figure[ocr]) |
| numpy |
Image array operations |
Extraction Engines (v2)
| Engine |
Priority |
Best For |
| Native (PyMuPDF) |
1st |
Raster images embedded in PDF |
| CV (connected-component) |
2nd |
Vector graphics, colored plots |
| Caption-anchored |
3rd |
Fallback when above engines fail |
The hybrid strategy (default) tries all three in order and validates results.
Detected Figure Fields
Each figure returned by FigureExtractor.detect_all() is a dict with these keys:
| Field |
Type |
Description |
number |
int |
Figure number |
page |
int |
Page index (0-based) |
bbox_pdf |
tuple |
Crop region in PDF points (x0, y0, x1, y1) |
bbox_px |
tuple |
Crop region in pixels (x0, y0, x1, y1) |
caption_text |
str |
Full caption text |
figure_type |
str |
One of: figure, scheme, chart, supplementary, extended_data |
sublabels |
list[str] |
Sub-figure labels, e.g. ["a","b","c"] |
image |
ndarray |
Cropped figure image (numpy array) |
engine_used |
str |
Engine that produced the crop: native, cv, or fallback |
list_figures() returns the same dicts without the image field.
Extension Support
Custom configurations via EXTEND.md. See Preferences section for paths and supported options.
© License & Copyright
Aut_Sci_Write — Autonomous Scientific Writer
- Author: Shuo Zhao
- License: MIT License
- Copyright: © 2026 Shuo Zhao. All rights reserved.
- Original Work: This is an original work created by the author. No reproduction, redistribution, or commercial use without explicit permission.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software... (See the LICENSE file in the root directory for the full MIT terms.)
This skill is part of the Aut_Sci_Write suite. For full license terms, see the LICENSE file in the project root.
1---2name: sci-figure3description: Extracts figures and sub-figures from academic PDF papers. Supports Fig/Figure, Scheme, Chart, Supplementary Figure, Extended Data Figure (Nature), and Chinese equivalents (图/方案/示意图/附图/补充图). Sub-figure label recognition supports (a)/(A)/a)/(i)/(1)/a. formats. High-quality PNG output at configurable DPI. Use when user asks to "extract figure", "截取文献图片", "提取子图", "get figure from paper", "Scheme", "方案图", "补充图", "Supplementary Figure", or "Extended Data".4license: AGPL-3.0-or-later5---67# Sci-Figure — Scientific Figure Extractor89Precisely extract figures and sub-figures from academic PDF papers.1011> **License note**: sci-figure is licensed under **AGPL-3.0-or-later** because it links [PyMuPDF (fitz)](https://pymupdf.readthedocs.io/), which is AGPL-licensed.1213## Installation1415Install the package from the skill directory before first use:1617```bash18cd ${SKILL_DIR}19pip install -e .20```2122This registers the `sh-sci-fig` CLI command. Requires Tesseract OCR:23- Windows: `winget install UB-Mannheim.TesseractOCR`24- Linux: `apt install tesseract-ocr`25- macOS: `brew install tesseract`2627## Preferences (EXTEND.md)2829Use Bash to check EXTEND.md existence (priority order):3031```bash32# Check project-level first33test -f .baoyu-skills/sci-figure/EXTEND.md && echo "project"3435# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)36test -f "$HOME/.baoyu-skills/sci-figure/EXTEND.md" && echo "user"37```3839**EXTEND.md Supports**: Default DPI | Default output format | Tesseract path4041## Usage4243```bash44sh-sci-fig <input.pdf> [options]45```4647## Options4849| Option | Short | Description | Default |50|--------|-------|-------------|---------|51| `<input>` | | PDF file path | Required |52| `--figure` | `-f` | Figure number (1, 2, 3...) | Required (except --list/--all) |53| `--subfigure` | `-s` | Sub-figure label (a, b, c...) | None (returns whole figure) |54| `--output` | `-o` | Output directory | Current directory |55| `--dpi` | `-d` | Output resolution | 600 |56| `--list` | `-l` | List all available figure numbers | false |57| `--all` | | Extract all figures | false |58| `--format` | | Output format (png/jpg) | png |59| `--strategy` | | Extraction strategy: hybrid/native/cv | hybrid |60| `--ocr` | | OCR engine: tesseract/easyocr/none | tesseract |61| `--render-page` | | Render full page with annotations | false |62| `--annotate` | | Draw bounding boxes on rendered page | false |63| `--bbox` | | Manual bbox override (x0,y0,x1,y1 in px) | None |64| `--no-trim` | | Disable whitespace trimming | false |65| `--debug` | | Enable debug logging | false |66| `--quiet` | `-q` | Suppress info messages | false |6768## Examples6970```bash71# Extract Figure 2, sub-figure c72sh-sci-fig paper.pdf -f 2 -s c7374# Extract entire Figure 375sh-sci-fig paper.pdf -f 37677# List all available figures in a PDF78sh-sci-fig paper.pdf --list7980# Extract all figures81sh-sci-fig paper.pdf --all8283# Custom output directory and DPI84sh-sci-fig paper.pdf -f 2 -s c -o ./output/ -d 3008586# Use EasyOCR for sub-figure label detection87sh-sci-fig paper.pdf --all --ocr easyocr8889# CV-only strategy (skip native extraction)90sh-sci-fig paper.pdf --all --strategy cv9192# Render page with annotated bounding boxes (debugging)93sh-sci-fig paper.pdf -f 1 --render-page --annotate9495# Manual bbox extraction (multimodal correction)96sh-sci-fig paper.pdf -f 1 --bbox 100,200,800,120097```9899**Output**:100```101Extracted: figure_2c.png (1920x1080, 600 DPI)102```103104## Error Handling105106| Scenario | Behavior |107|----------|----------|108| Figure number not found | Error + list all available figure numbers |109| OCR recognition failed | Return entire figure region |110| Sub-figure split failed | Return entire figure region |111| No sub-figure labels found | Return entire figure region |112113## Tech Stack114115| Library | Role |116|---------|------|117| pdfplumber | Text + coordinate extraction (caption detection) |118| PyMuPDF (fitz) | Native image extraction + high-quality page rendering |119| opencv-python | CV region detection, connected-component analysis, content validation |120| Pillow | Final cropping, format conversion |121| pytesseract | OCR for sub-figure label recognition (default) |122| easyocr | Alternative OCR engine (optional, `pip install sci-figure[ocr]`) |123| numpy | Image array operations |124125## Extraction Engines (v2)126127| Engine | Priority | Best For |128|--------|----------|----------|129| Native (PyMuPDF) | 1st | Raster images embedded in PDF |130| CV (connected-component) | 2nd | Vector graphics, colored plots |131| Caption-anchored | 3rd | Fallback when above engines fail |132133The `hybrid` strategy (default) tries all three in order and validates results.134135## Detected Figure Fields136137Each figure returned by `FigureExtractor.detect_all()` is a dict with these keys:138139| Field | Type | Description |140|-------|------|-------------|141| `number` | int | Figure number |142| `page` | int | Page index (0-based) |143| `bbox_pdf` | tuple | Crop region in PDF points (x0, y0, x1, y1) |144| `bbox_px` | tuple | Crop region in pixels (x0, y0, x1, y1) |145| `caption_text` | str | Full caption text |146| `figure_type` | str | One of: `figure`, `scheme`, `chart`, `supplementary`, `extended_data` |147| `sublabels` | list[str] | Sub-figure labels, e.g. `["a","b","c"]` |148| `image` | ndarray | Cropped figure image (numpy array) |149| `engine_used` | str | Engine that produced the crop: `native`, `cv`, or `fallback` |150151`list_figures()` returns the same dicts without the `image` field.152153## Extension Support154155Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.156157158159160161---162163## © License & Copyright164165**Aut_Sci_Write** — Autonomous Scientific Writer166167- **Author**: Shuo Zhao168- **License**: MIT License169- **Copyright**: © 2026 Shuo Zhao. All rights reserved.170- **Original Work**: This is an original work created by the author. No reproduction, redistribution, or commercial use without explicit permission.171 **Permission is hereby granted**, free of charge, to any person obtaining a copy of this software... (**See the LICENSE file in the root directory for the full MIT terms.**)172173---174175*This skill is part of the Aut_Sci_Write suite. For full license terms, see the [LICENSE](../LICENSE) file in the project root.*176---177