Metadata-Version: 2.4
Name: sciglyph
Version: 0.1.2
Summary: Publication-quality scientific illustration in pure matplotlib - no BioRender, no Illustrator
Author: Guo Cheng
License: MIT
Project-URL: Homepage, https://github.com/GuoCheng24/sciglyph
Project-URL: Issues, https://github.com/GuoCheng24/sciglyph/issues
Keywords: matplotlib,scientific-figures,publication,illustration,graphical-abstract,bioinformatics,deep-learning,diagram
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib>=3.5
Requires-Dist: numpy>=1.20
Dynamic: license-file

# sciglyph

[![PyPI](https://img.shields.io/pypi/v/sciglyph)](https://pypi.org/project/sciglyph/) [![test](https://github.com/GuoCheng24/sciglyph/actions/workflows/test.yml/badge.svg)](https://github.com/GuoCheng24/sciglyph/actions/workflows/test.yml) [![python](https://img.shields.io/badge/python-3.9%2B-blue)](https://www.python.org/) [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)

**Publication-quality scientific illustration in pure matplotlib — no BioRender, no Illustrator.**

Overview figures and architecture diagrams are usually drawn by hand in a
subscription tool. That makes them pretty, but also unreproducible: you cannot
diff them, you cannot regenerate them when the numbers change, and you cannot
put them under version control.

`sciglyph` gives you the primitives to draw the same figures as **code**.

<p align="center">
  <img src="gallery/overview_figure.png" width="88%">
</p>

<p align="center">
  <img src="gallery/architecture.png" width="100%">
</p>

<sub>Both figures above are generated by the scripts in
<a href="examples/">examples/</a> — nothing was touched by hand. The content is
synthetic; swap in your own numbers and the layout carries over.</sub>

---

## Why

| | subscription tools | `sciglyph` |
|---|---|---|
| Reproducible | ✗ manual pixel-pushing | ✓ a script |
| Version control | ✗ binary blobs | ✓ diffable source |
| Data-driven | ✗ retype every number | ✓ read straight from your results |
| Vector output | ~ depends on export | ✓ PDF/SVG with editable text |
| Cost | subscription | free, MIT |

## Install

```bash
pip install sciglyph
```

Only `matplotlib` and `numpy`. Nothing else.

## Quick start

```python
import matplotlib.pyplot as plt
from sciglyph import bio, set_canvas, report, RC

plt.rcParams.update(RC)
fig = plt.figure(figsize=(7.2, 3.0), dpi=300)
ax = fig.add_axes([0, 0, 1, 1]); ax.set_xlim(0, 1); ax.set_ylim(0, 1); ax.axis("off")
set_canvas(fig)                      # required on non-square canvases

bio.person(ax, .08, .55, s=.30)
bio.dna(ax, .25, .55, w=.05, h=.45, n=2)
bio.cell(ax, .42, .55, r=.06, seed=1)
bio.seq_logo(ax, .60, .40, [("A", .6), ("C", .9), ("G", .4), ("T", .7)], w=.03)

report(fig, ax)                      # catch text collisions before saving
fig.savefig("figure.pdf", bbox_inches="tight")
```

That block is runnable as it stands — it saves `figure.pdf` and prints the layout
report on the way.

The two full examples behind the images above live in the repository rather than
the wheel, so they need a clone:

```bash
git clone https://github.com/GuoCheng24/sciglyph && cd sciglyph
python examples/overview_figure.py    # -> gallery/overview_figure.png
python examples/architecture.py       # -> gallery/architecture.png
```

## What's included

**`sciglyph.bio`** — glyphs for Nature/Science-style overview figures:
`person` (cohorts) · `dna` · `cell` · `lipid` · `metabolite` ·
`nucleosome_chain` · `umap_layer` (the stacked atlas look) ·
`seq_logo` (information-scaled letters, no logomaker needed) ·
`stacked_planes` · `rbox` · `arr`

**`sciglyph.arch`** — glyphs for architecture diagrams:
`cuboid` / `feature_stack` (3-D feature blocks) · `trapezoid` (encoders) ·
`module_stack` (`Conv|BN|ReLU` bars) · `dashed_group` (the `(a)/(b)/(c)`
language) · `flow` · `op_circle` · `snowflake` (frozen backbone) ·
`image_thumb` · `embedding_space` (contrastive panels) · `loss_tag` · `bracket`

**`sciglyph.layout`** — pre-flight collision detection.

## Catching layout bugs before you save

When a figure breaks, it is almost never the artwork — it is the layout.
`report()` uses the real rendered bounding boxes to find overlapping text, so
you do not have to hunt for it by eye:

```python
report(fig, ax)
# [sciglyph.layout] 36 text objects
#   ! 'CD4 Treg/-FOXP3' x 'SMR' overlap 92%
```

It also works from the command line on any script that exposes `fig` and `ax`:

```bash
python -m sciglyph.layout my_figure.py
```

It checks three things, each of which shipped a broken figure before it existed:

| check | what it catches |
|---|---|
| text overlap | two labels drawn over each other |
| **artwork overlap** | a row of boxes laid out slightly too wide, so each one covers its neighbour — the strings may not overlap at all, so text-level checks miss it entirely |
| **missing glyphs** | a character the font cannot draw, rendered as an empty box. Symbols typed as literals (`✓`, `❄`) are the usual casualty |

Two kinds of overlap are deliberately *not* reported, because they are the
layout working: a panel containing its contents, and an unfilled dashed shape —
a ring drawn around the thing it annotates.

**These are geometric checks.** Whether the figure actually *reads* well still
needs your eyes.

## Notes from actually shipping these figures

- **Call `set_canvas(fig)`.** In `[0,1]` coordinates a "circle" is `r·W` wide
  and `r·H` tall. On a 12×3 canvas, every circle becomes a rugby ball.
- **Anchor arrows to what `feature_stack` returns**, not to hard-coded
  coordinates — otherwise changing the number of blocks silently breaks them.
- **Never put symbol codepoints in figure text.** `❄` (U+2744) is missing from
  most sans fonts and renders as a tofu box. Draw it (`arch.snowflake`).
- **Overlapping translucent fills blend into one muddy colour.** Keep the fill
  under `alpha=0.15`, stroke each curve, *and* offset the peaks. Tuning alpha
  alone will not save you.
- **Fonts:** Arial/Helvetica are often absent on Linux. `RC` falls back to
  Liberation Sans (metric-compatible with Arial) and sets `pdf.fonttype=42`
  so text stays editable in the PDF — a hard requirement at most journals.
- **Don't move elements toward whitespace.** Whitespace relocates, it does not
  disappear. Decide which row an element belongs to, move it as a group, then
  verify with the quadrant ink distribution.

## Honest scope

This gets you clean flat schematics combined with data panels — the register
of a Nature/Science overview figure or a TPAMI architecture diagram. It will
**not** reproduce hand-drawn illustration (shaded organs, textured cells,
gradients). For that, embed a CC-BY asset and cite it rather than fake it.

## Who maintains this

Guo Cheng, University of Chinese Academy of Sciences — medical imaging and machine
learning methods. This tool came out of needing to regenerate a figure every time the numbers changed, and not wanting to redraw it by hand each time.

Corrections, bug reports and feature requests all go to
[Issues](https://github.com/GuoCheng24/sciglyph/issues). Please open one rather than
emailing: a public answer helps whoever hits the same thing next, and it is
searchable.

## License

MIT © Guo Cheng

## 关于那行 star 提示

调用 `report()` 时，`sciglyph` 会在**第 5 次和第 25 次**往 stderr 写一行，提一句这个仓库在哪。**一辈子只有这两次**，此外再不出声。

它不会出现在：管道或重定向里（stderr 不是终端就直接返回，连计数文件都不建）、CI 环境里（`CI` / `GITHUB_ACTIONS`）。它写的是 stderr 而非 stdout，所以不会污染你的数据输出；它包在 `try/finally` 里且吞掉自身所有异常，**不会改变退出码，也不会影响结果**。

永久关掉：

```bash
export SCIGLYPH_NO_NUDGE=1
```

计数存在 `$XDG_STATE_HOME/sciglyph/usage.json`（默认 `~/.local/state/sciglyph/usage.json`），删掉即重置。
