ridgeplot is a Python package for beautiful, interactive ridgeline plots built on Plotly.
- Read this file first, then the most relevant source file(s).
- Prefer local docs and tests over memory; do not guess behavior.
- If requirements are unclear or risky, ask a concrete question before changing code.
- Python >=3.10
- Plotly graph objects (dependency is
plotly>=5.20) - Line length 100, formatting with ruff
- Docstrings are NumPy style
- Type annotations are modern and throughout with strict checking via pyright
# Initialize full development environment (recommended for first-time setup)
# This creates .venv, installs dependencies, and sets up pre-commit hooks
make init
# Activate the virtual environment
source .venv/bin/activate# Run all test suites (unit + e2e + cicd_utils)
uvx tox -m tests
# Run a specific test suite
uvx tox -e tests-unit # Unit tests with coverage
uvx tox -e tests-e2e # End-to-end tests
uvx tox -e tests-cicd_utils # CI/CD utilities tests
# Run pytest directly with custom options
uvx tox -e pytest -- tests/unit/test_init.py --no-cov
uvx tox -e pytest -- -k "test_specific_function" --no-cov# Run the main static checks
uvx tox -m static-quick
# Run the entire suite of static checks (incl. all pre-commit hooks)
# If running from the main branch, you'll need
# to skip the 'no-commit-to-branch' check with:
SKIP='no-commit-to-branch' uvx tox -m static
# Run all pre-commit hooks on all files
uvx pre-commit run --all-files
# Run specific pre-commit hooks
uvx pre-commit run ruff-format --all-files
# Run type checking with pyright only
uvx tox -e typing# Build static documentation
uvx tox -e docs-staticsrc/ridgeplot/
├── __init__.py # Public API exports
├── _ridgeplot.py # Main ridgeplot() function
├── _figure_factory.py # Plotly Figure construction
├── _kde.py # Kernel Density Estimation
├── _hist.py # Histogram binning
├── _types.py # Type aliases and type guards
├── _utils.py # Utility functions
├── _missing.py # Sentinel for missing values
├── _version.py # Version string (setuptools-scm)
├── _color/ # Color handling
│ ├── colorscale.py # Colorscale resolution
│ ├── css_colors.py # CSS color parsing
│ ├── interpolation.py # Color interpolation
│ └── utils.py # Color utilities
├── _obj/traces/ # Trace objects
│ ├── area.py # Area trace (filled curves)
│ ├── bar.py # Bar trace (histograms)
│ └── base.py # Base trace class
├── _vendor/ # Vendored dependencies
└── datasets/ # Built-in datasets
└── data/ # CSV data files
tests/
├── conftest.py # Shared pytest fixtures
├── unit/ # Unit tests for individual modules
├── e2e/ # End-to-end tests with expected outputs
│ └── artifacts/ # JSON artifacts for e2e comparisons
└── cicd_utils/ # Tests for CI/CD utilities
cicd_utils/ # CI/CD helper modules
├── cicd/ # Scripts and test helpers
└── ridgeplot_examples/ # Example implementations for docs/testing
The public API exposes one main function: ridgeplot.ridgeplot(...) -> go.Figure
The ridgeplot() docstring in src/ridgeplot/_ridgeplot.py contains the API contract.
ridgeplot.datasets.load_probly() and
ridgeplot.datasets.load_lincoln_weather() are legacy loaders kept for
backwards compatibility only.
- Users call
ridgeplot(samples=...)orridgeplot(densities=...). - If samples are provided, KDE in
_kde.pyor histogram binning in_hist.pyproduces densities. - Densities are normalised if the
normparameter is set. create_ridgeplot()in_figure_factory.pybuilds the Plotly Figure by resolving colors, creating traces, and applying layout settings.- The function returns a
plotly.graph_objects.Figure.
| File | Purpose |
|---|---|
src/ridgeplot/_ridgeplot.py |
Main ridgeplot() function |
src/ridgeplot/_figure_factory.py |
Figure construction logic |
src/ridgeplot/_types.py |
All type aliases and guards |
tests/unit/test_ridgeplot.py |
Core function tests |
cicd_utils/ridgeplot_examples/ |
Example scripts for docs |
docs/ |
User and developer docs |
tox.ini |
CI environment definitions |
ruff.toml |
Linting configuration |
Documentation: https://ridgeplot.readthedocs.io/en/stable/
- Start with
src/ridgeplot/_ridgeplot.pyto understand the entry point. - Add parameters following existing patterns and deprecation handling.
- Update types in
src/ridgeplot/_types.pywhen introducing new structures. - Add tests in
tests/unit/with good coverage. - Update docstrings to match the new behavior.
- Write a failing test first.
- Fix the issue with minimal changes.
- Ensure tests and type checks pass.
- Verify docstrings remain accurate.
- Uses pyright in strict mode (see
pyrightconfig.json) - All functions must be fully typed, following modern Python typing practices and existing project conventions.
- Use
TYPE_CHECKINGblocks for import-only types - Use type guards for runtime type narrowing (see
_types.py) - Follow this general principle for user-facing code: be contravariant in the input type and covariant in the output type
- Add type aliases close to their usage. If widely used, place in
_types.py.
Handling deprecated parameters:
if deprecated_param is not MISSING:
if new_param is not None:
raise ValueError("Cannot use both...")
warnings.warn("...", DeprecationWarning, stacklevel=2)
new_param = deprecated_paramType narrowing with guards:
if is_shallow_samples(samples):
samples = nest_shallow_collection(samples)
samples = cast("Samples", samples)Lazy imports for performance:
# Heavy imports inside functions to reduce import time
def _coerce_to_densities(...):
from ridgeplot._kde import estimate_densities # statsmodels is slow to import- Use
--no-covflag during development for faster test runs - Run targeted tests via:
uvx tox -e pytest -- tests/unit/test_foo.py -k "test_bar" --no-cov - The
tests/e2e/artifacts/directory contains expected Plotly Figure JSON for e2e tests
GitHub Actions runs tests on Python 3.10–3.14 across Ubuntu, macOS, and Windows. Codecov minimums are 98% overall and 100% diff coverage for new code.
- Run tests after changes when feasible, starting with the smallest relevant subset.
- Run
uvx tox -e typingif types are touched or errors are likely. - Run
uvx pre-commit run ruff-format --all-filesto format code. - Preserve deprecation behavior and public API stability.
- Keep changes minimal and aligned with existing patterns.
- Respect existing patterns - this is a mature codebase with consistent style.