This release is a pre-release and may not be stable for production use.
SecretPlots
Publication-ready scientific figures in a few readable lines of Python.
Journal presets · statistics built in · colour-blind-safe palettes · fonts embedded
Documentation · Gallery · Journal-ready figures · Changelog · Report a bug
import SecretPlots as sp
sp.use(preset="nature") # 89 mm column, 5–7 pt text, 300 dpi
(
sp.box(cells, x="treatment", y="area")
.points() # show every cell
.compare(ref="Control", correction="holm") # significance brackets
.labels(x="", y="Cell area (µm²)")
.save("figure1.pdf") # fonts embedded, ready to upload
)
Status: version 3.0 is a ground-up rewrite and is in alpha. APIs may still change. It is not compatible with the 0.1.x releases; pin
SecretPlots<1if you depend on the old API.
Why SecretPlots?
- Journal presets. Nature, Science, Cell, PNAS, AHA, Elsevier, Springer, IEEE, ACM and NeurIPS presets set column widths, font limits, dpi and file formats from each publisher's author guidelines.
- Statistics where you need them. Significance brackets with Holm or Bonferroni correction, confidence bands, prediction intervals, linear fits with R², KDEs and hierarchical clustering. Every number is available as a table.
- Every observation visible. Points over boxes, individual trajectories under means, rainclouds and rugs, the patterns reviewers ask for with small samples.
- Colour-blind safe. Palettes and colormaps come from
SecretColors. Unsafe maps are
flagged, and a
print-bwtheme renders the figure in greys. - Readable, chainable API. One constructor plus small steps.
plot.options()lists every step;plot.options("legend")explains one. - Honest defaults. Missing data raises instead of being silently dropped.
Font and palette fallbacks are reported, and
plot.explain("font_size")says where any style value came from.
Installation
pip install --pre SecretPlots # or: uv add --prerelease=allow SecretPlots
The --pre flag is needed while 3.0 is in alpha. Without it, pip installs the
legacy 0.1.x release.
Requires Python 3.12+. Depends only on matplotlib, numpy, pandas and SecretColors.
Gallery
Every image below is unretouched SecretPlots output at Nature single-column size. The gallery has the complete, runnable code for each.
Compare groups, with the statistics
sp.box(viability, x="dose", y="viability").points().compare(ref="Vehicle", correction="holm", format="stars")
sp.raincloud(stroop, x="condition", y="rt").compare(ref="Congruent", format="stars")
Follow change over time
sp.line(tumours, x="day", y="volume", hue="arm", units="mouse", error="ci").endlabels().log("y")
sp.line(pk, x="hours", y="conc", hue="dose", error="sd").errorbars("bars").markers().log("y")
Find the pattern in a matrix
sp.heatmap(expression).scale("row").groups(rows="pathway").cluster(cols=False).tracks(cols={"Condition": condition})
sp.heatmap(cohort.corr(), square=True).mask("upper").cmap("tol_bu_rd", center=0).values(".2f")
Relationships and distributions
sp.scatter(genes, x="lfc", y="log_p", hue="call").refline(-1, 1, axis="x").refline(2, axis="y")
sp.scatter(biopsies, x="bmi", y="lipid", hue="tissue").fit("linear", stats=True)
sp.histogram(serum, x="level", hue="cohort", stat="density").kde().show_n()
sp.violin(behaviour, x="genotype", y="score", hue="sex", split=True, inner="quartiles")
One figure, any journal
Presets describe where a figure is going; themes describe how it looks. Switch either one without touching your plotting code:
sp.use(preset="nature") # for the whole session
plot.preset("ieee") # or for one plot
plot.size(width="double", height="60mm") # the journal's named widths, or any length
plot.theme("print-bw").encode_groups() # greyscale with dashes and markers
| Kind | Presets |
|---|---|
| Journals | nature · science · cell · pnas · aha · elsevier · springer · ieee · acm · neurips |
| Everyday | screen (default) · web · a4 · letter · slide-16x9 · poster |
| Newsroom | bbc · ft-like · economist-like · nyt-like · wapo-like |
Journal presets cite the guidelines they were built from. If you set a value
outside a journal's limits, you get a LimitExceededWarning instead of a
silent change. Newsroom presets ending in -like are inspired by publicly
visible chart conventions; they are not affiliated with those publishers and
use open fallback fonts. You can write your own preset
in a few lines of TOML.
Plot types
sp.bar |
Means, sums or values per category; error bars, groups, stacks, value labels |
sp.scatter |
Colour, size and marker encodings; linear and LOWESS fits |
sp.line |
Means with CI/SD/SEM/PI bands, fan charts, individual units, end labels |
sp.area, sp.fill_between |
Stacked and 100% areas, envelopes, split by sign, gradients |
sp.histogram |
Counts, percent or density; KDE, rug, cumulative, layered, stacked or dodged |
sp.heatmap |
Colormaps, z-scoring, clustering, groups, annotation tracks, masks |
sp.box |
Points, means, sample sizes, significance brackets |
sp.violin, sp.raincloud |
Split violins, inner box/quartiles, half-violin rainclouds |
Find any option without leaving Python
plot.options() # every chainable step for this plot
plot.options("legend") # one step's parameters, allowed values and defaults
sp.BarPlot.options("values") # explore without data
sp.theme_options() # every style field accepted by .theme(...)
Development
uv sync --group dev --group docs
uv run pre-commit install
uv run pytest --mpl # tests, including image comparisons
uv run python scripts/render_docs.py # regenerate documentation figures
uv run mkdocs serve # preview the documentation
See CONTRIBUTING.md for adding presets and documentation. Bug reports, preset requests and pull requests are very welcome.
License
MIT © Rohit Suratekar and contributors. Colour palettes and colormaps by SecretColors.
Metadata
Release files for SecretPlots 3.0.0a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| secretplots-3.0.0a1.tar.gz | 563.4 kB | Without provenance | Details for secretplots-3.0.0a1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| secretplots-3.0.0a1-py3-none-any.whl | Python 3 | none | any | Details for secretplots-3.0.0a1-py3-none-any.whl |
Total release size: 719.7 kB
Release files / secretplots-3.0.0a1.tar.gz
| Download URL | secretplots-3.0.0a1.tar.gz |
|---|---|
| Size | 563.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
74dd1b25200bfb3254c5a97663800a17111817ed5f10e9cd778ad61804cc8093
|
|
BLAKE2b-256 checksum How to use checksums |
765dbc8768a756e6bb989749713cf6473db33ca231bfdad626465123faf42d61
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / secretplots-3.0.0a1-py3-none-any.whl
| Download URL | secretplots-3.0.0a1-py3-none-any.whl |
|---|---|
| Size | 156.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
af4687ea559faf0dc528e040b1b4a64591b129e73c59abbaad48144d34a508c4
|
|
BLAKE2b-256 checksum How to use checksums |
9fea69e3a3ccf4bba6a6a819ef5074d29b4a0f7e479c626e06715d6e67c53582
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for SecretPlots 3.0.0a1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.