Skip to main content
Pre-release

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

SecretPlots

Publication-ready scientific figures in a few readable lines of Python.
Journal presets · statistics built in · colour-blind-safe palettes · fonts embedded

PyPI Python versions CI Documentation MIT license

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<1 if 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-bw theme 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.

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

Dose-response box plot with significance stars Raincloud plot of reaction times
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

Tumour growth curves with individual animals Pharmacokinetic curves on a log axis
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

Clustered expression heatmap with pathway groups Lower-triangle correlation 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

Volcano plot Scatter plot with linear fits and R²
Overlaid density histograms with KDE Split violin plots
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)

Source distribution for SecretPlots 3.0.0a1
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)

Table of built distributions (wheels) for SecretPlots 3.0.0a1
File Interpreter ABI Platform Actions
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page