8000 GitHub - ccwang002/p9beeswarm: beeswarm plot for plotnine · GitHub
[go: up one dir, main page]

Skip to content
7FFF

About

beeswarm plot for plotnine

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

p9beeswarm

p9beeswarm provides beeswarm-style geoms for plotnine, modelled after the R ggbeeswarm package. The distribution also exposes the upstream algorithm compatibility modules as beeswarm and vipor, mirroring the corresponding R packages.

Upstream R tools

p9beeswarm is heavily inspired by the following upstream R packages. The Python implementations and compatibility tests follow their algorithms and plotting behavior:

Package License Authors
beeswarm Artistic License 2.0 Aron Eklund, James Trimble, et al.
vipor GPL (>= 2) Scott Sherrill-Mix, Erik Clarke, et al.
ggbeeswarm GPL (>= 3) Erik Clarke, Scott Sherrill-Mix, Charlotte Dawson, et al.

Installation

Install p9beeswarm from PyPI with:

python -m pip install p9beeswarm

Usage

import plotnine as p9
from plotnine.data import penguins
from p9beeswarm import geom_quasirandom

penguins_plot = (
    p9.ggplot(
        penguins,
        p9.aes(x="species", y="body_mass_g", color="species"),
    )
    + geom_quasirandom()
    + p9.labs(
        title="Penguin body mass by species",
        x="Species",
        y="Body mass (g)",
    )
    + p9.theme_bw()
)

Rendered output:

Penguin body mass beeswarm plot by p9beeswarm

The side-by-side ggbeeswarm examples recreate the upstream README plots with both the Python and R implementations. Render them with:

quarto render docs/ggbeeswarm-examples.qmd

The README figure is generated by docs/update_readme_figure.py. If you change the example above, regenerate the image with:

uv run python docs/update_readme_figure.py

Implementations and reproducibility

The table below records the Python implementation and its upstream R implementation. “100% reproducible” means that repeated builds with the same data and parameters do not draw random numbers. Methods marked as random can still be made reproducible in Python by passing a fixed random_state; without one, their point positions may change between builds.

Plotnine API / method Upstream R implementation 100% reproducible? Notes
geom_quasirandom(method="quasirandom") ggbeeswarm::geom_quasirandom → vipor::offsetX / vipor::offsetSingleGroup Yes Uses the deterministic van der Corput sequence. This is the default quasirandom method.
geom_quasirandom(method="maxout|minout|smiley|frowney") ggbeeswarm::geom_quasirandom → vipor::offsetX / vipor::offsetSingleGroup Yes Density and alternating extreme placement do not use random draws.
geom_quasirandom(method="pseudorandom") ggbeeswarm::geom_quasirandom → vipor::offsetX / vipor::offsetSingleGroup No (unless seeded) Explicitly generates random offsets; pass random_state for repeatable Python plots.
geom_quasirandom(method="tukey|tukeyDense") ggbeeswarm::geom_quasirandom → vipor::offsetX / vipor::tukeyTexture No (unless seeded) Tukey texture generates random permutations and jitter; pass random_state for repeatable Python plots.
geom_beeswarm(method="swarm") ggbeeswarm::geom_beeswarm → beeswarm::swarmx Yes* The default priority="ascending" and corral="none" are deterministic. priority="random" or corral="random" introduces randomness.
geom_beeswarm(method="compactswarm") ggbeeswarm::geom_beeswarm → beeswarm::swarmx(compact=TRUE) Yes* Same priority and corral caveat as swarm.
geom_beeswarm(method="center|square|hex") ggbeeswarm::geom_beeswarm internal grid placement (center, square, or hex) Yes* Grid placement is deterministic; corral="random" is the exception.

*The beeswarm rows are deterministic with their default options. Any method that uses a random priority or corral is not 100% reproducible unless a seed is supplied.

License

p9beeswarm is licensed under the GNU GPLv3 or later.

Testing

The package is managed with [uv]. The core test suite covers the beeswarm and vipor compatibility modules, along with the plotnine position/geom integration:

uv run --no-default-groups --group test pytest

Upstream comparison tests

Beyond the core suite, the tests include parity checks against the original R packages. These tests use rpy2 to call the upstream R implementations and assert that the Python results match numerically:

uv run --no-default-groups --group test --group r-test pytest

The R dependencies are pinned in renv.lock and restored by the GitHub Actions workflow with r-lib/actions/setup-renv. To update the pinned versions, run these commands from the repository root:

Rscript -e 'if (!requireNamespace("renv", quietly = TRUE)) install.packages("renv", repos = "https://cloud.r-project.org")'
Rscript -e 'renv::restore(prompt = FALSE)'
Rscript -e 'renv::update(c("beeswarm", "vipor", "ggbeeswarm", "ggplot2"), prompt = FALSE)'
Rscript -e 'renv::snapshot(prompt = FALSE)'

Review the resulting renv.lock diff, run the upstream comparison tests, and commit the updated lockfile along with any dependency changes.

Type checking

Type-check using mypy.

uv run --no-default-groups --group test --group r-test mypy src/ tests/

About

beeswarm plot for plotnine

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

0