11# ridgeplot Development Guide for AI Agents
22
3- ` ridgeplot ` is a Python package that provides a simple interface for plotting beautiful and interactive ridgeline plots within the extensive Plotly ecosystem .
3+ ` ridgeplot ` is a Python package for beautiful, interactive ridgeline plots built on Plotly.
44
5- This file provides guidance for AI assistants working with the ridgeplot codebase.
5+ ## Start Here
66
7- ## Public API Overview
7+ - Read this file first, then the most relevant source file(s).
8+ - Prefer local docs and tests over memory; do not guess behavior.
9+ - If requirements are unclear or risky, ask a concrete question before changing code.
810
9- The library only exposes three public functions to end users.
11+ ## Stack and Style Constraints
1012
11- Two of these functions are toy dataset loaders (` ridgeplot.datasets.load_probly() ` and
12- ` ridgeplot.datasets.load_lincoln_weather() ` ) but they are not the focus on the project and are only exposed for backwards compatibility reasons.
13+ - Python >=3.10
14+ - Plotly graph objects (dependency is ` plotly>=5.20 ` )
15+ - Line length 100, formatting with ruff
16+ - Docstrings are NumPy style
17+ - Type annotations are modern and throughout with strict checking via pyright
1318
14- The third function (` ridgeplot.ridgeplot() ` ) is a Plotly Figure (
15- ` plotly.graph_objects.Figure ` ) factory function, and it's the focus of this project. See its docstring at
16- ` src/ridgeplot/_ridgeplot.py ` for full details.
17-
18- ## .cursor rules directory
19-
20- You can check
21- ` .cursor/rules ` before providing recommendations or generating code. This directory contains the authoritative rules for all development aspects.
22-
23- To find the relevant rules:
24-
25- 1 . Find ALL .md files in ` .cursor/rules `
26- 2 . Read ALL relevant rules files, based on the filetypes/languages/libraries/tasks/folders involved (e.g., .tsx, .css, .java, React,
27- ` //web/src/pages/home ` , etc)
28- 3 . If unsure, read metadata (first 5 lines) of any .mdc file to check rule scope/description/keywords
29-
30- ** For common tasks, you can check these specific files:**
31-
32- - Bazel/testing: ` .cursor/rules/bazel-test-execution.mdc `
33- - Java code: ` .cursor/rules/java-conventions.mdc `
34- - TypeScript/web: ` .cursor/rules/web-conventions.mdc `
35- - Pull requests: ` .cursor/rules/pull-request-conventions.mdc `
36-
37- ** Documentation:** https://ridgeplot.readthedocs.io/en/stable/
38-
39- ** Python Version** : Requires Python 3.10+
40-
41- ## Common Commands
19+ ## Quick Commands
4220
4321### Environment Setup
4422
@@ -50,7 +28,7 @@ make init
5028# Use a different Python version if needed (default is python3.10)
5129BASE_PYTHON=python3.14 make init
5230
53- # Offline mode (uses cached packages only) - useful when the internet is down
31+ # Offline mode (uses cached packages only)
5432OFFLINE=1 make init
5533
5634# Activate the virtual environment
@@ -60,7 +38,7 @@ source .venv/bin/activate
6038### Running Tests
6139
6240``` bash
63- # Run all test suits (unit + e2e + cicd_utils)
41+ # Run all test suites (unit + e2e + cicd_utils)
6442tox -m tests
6543
6644# Run a specific test suite
@@ -99,7 +77,7 @@ tox -e typing
9977tox -e docs-static
10078```
10179
102- ## Architecture Overview
80+ ## Project Map
10381
10482```
10583src/ridgeplot/
@@ -137,63 +115,68 @@ cicd_utils/ # CI/CD helper modules
137115└── ridgeplot_examples/ # Example implementations for docs/testing
138116```
139117
140- ### Key Data Flow
118+ ## Public API
141119
142- 1 . User calls ` ridgeplot(samples=...) ` or ` ridgeplot(densities=...) `
143- 2 . If samples provided → KDE (` _kde.py ` ) or histogram binning (` _hist.py ` ) produces densities
144- 3 . Densities are normalised if ` norm ` parameter is set
145- 4 . ` create_ridgeplot() ` in ` _figure_factory.py ` builds the Plotly Figure:
146- - Resolves colorscale and computes colors for each trace
147- - Creates trace objects (area or bar) for each density
148- - Applies layout settings (spacing, padding, axes)
149- 5 . Returns a ` plotly.graph_objects.Figure ` that users can further customise
120+ The public API exposes one main function: ` ridgeplot.ridgeplot(...) -> go.Figure `
150121
151- ### Type System
122+ The ` ridgeplot() ` docstring in ` src/ridgeplot/_ridgeplot.py ` contains the API contract.
152123
153- The codebase uses extensive type annotations. Key types in ` _types.py ` :
124+ ` ridgeplot.datasets.load_probly() ` and
125+ ` ridgeplot.datasets.load_lincoln_weather() ` are legacy loaders kept for
126+ backwards compatibility only.
154127
155- - ** Samples/Densities** : Ragged 3D arrays ` [rows][traces_per_row][values] `
156- - ** ShallowSamples/ShallowDensities** : 2D arrays (one trace per row)
157- - ** ColorScale** : ` Collection[tuple[float, Color]] `
158- - ** Type guards** : ` is_shallow_samples() ` , ` is_densities() ` , etc.
128+ ## Key Data Flow
159129
160- ## Code Style Guidelines
130+ 1 . Users call ` ridgeplot(samples=...) ` or ` ridgeplot(densities=...) ` .
131+ 2 . If samples are provided, KDE in ` _kde.py ` or histogram binning in ` _hist.py `
132+ produces densities.
133+ 3 . Densities are normalised if the ` norm ` parameter is set.
134+ 4 . ` create_ridgeplot() ` in ` _figure_factory.py ` builds the Plotly Figure by
135+ resolving colors, creating traces, and applying layout settings.
136+ 5 . The function returns a ` plotly.graph_objects.Figure ` .
161137
162- ### General
138+ ## Key Files to Know
163139
164- - ** Python version** : 3.10+ (uses modern typing features)
165- - ** Line length** : 100 characters
166- - ** Formatting** : Ruff (replaces black, isort, flake8)
167- - ** Imports** : Always include ` from __future__ import annotations `
168- - ** Docstrings** : NumPy style
169- - ** Type annotations** : Use full and modern type annotations throughout with strict pyright checking
140+ | File | Purpose |
141+ | ------------------------------------| -----------------------------|
142+ | ` src/ridgeplot/_ridgeplot.py ` | Main ` ridgeplot() ` function |
143+ | ` src/ridgeplot/_figure_factory.py ` | Figure construction logic |
144+ | ` src/ridgeplot/_types.py ` | All type aliases and guards |
145+ | ` tests/unit/test_ridgeplot.py ` | Core function tests |
146+ | ` cicd_utils/ridgeplot_examples/ ` | Example scripts for docs |
147+ | ` docs/ ` | User and developer docs |
148+ | ` tox.ini ` | CI environment definitions |
149+ | ` ruff.toml ` | Linting configuration |
170150
171- ### Type Annotations
151+ Documentation: https://ridgeplot.readthedocs.io/en/stable/
172152
173- - All functions must be fully typed
174- - Use ` TYPE_CHECKING ` blocks for import-only types
175- - Uses ** pyright** in strict mode (see ` pyrightconfig.json ` )
176- - Use type guards for runtime type narrowing (see ` _types.py ` )
177- - Follow this general principle for user-facing code: be contravariant in the input type and covariant in the output type
178-
179- ## Working with This Codebase
153+ ## Workflow Expectations
180154
181155### When Adding New Features
182156
183- 1 . Start with ` _ridgeplot.py ` to understand the main entry point
184- 2 . Add new parameters following the existing patterns (with proper deprecation handling)
185- 3 . Update type annotations in ` _types.py ` if introducing new data structures
186- 4 . Add tests in ` tests/unit/ ` with good coverage
187- 5 . Update documentation in docstrings following the existing conventions
157+ 1 . Start with ` src/ridgeplot/ _ridgeplot.py` to understand the entry point.
158+ 2 . Add parameters following existing patterns and deprecation handling.
159+ 3 . Update types in ` src/ridgeplot/ _types.py` when introducing new structures.
160+ 4 . Add tests in ` tests/unit/ ` with good coverage.
161+ 5 . Update docstrings to match the new behavior.
188162
189163### When Fixing Bugs
190164
191- 1 . Write a failing test first
192- 2 . Fix the issue with minimal changes
193- 3 . Ensure all existing tests pass
194- 4 . Check type annotations are correct
165+ 1 . Write a failing test first.
166+ 2 . Fix the issue with minimal changes.
167+ 3 . Ensure tests and type checks pass.
168+ 4 . Verify docstrings remain accurate.
195169
196- ### Common Patterns
170+ ### Type Annotations
171+
172+ - Uses ** pyright** in strict mode (see ` pyrightconfig.json ` )
173+ - All functions must be fully typed, following modern Python typing practices and existing project conventions.
174+ - Use ` TYPE_CHECKING ` blocks for import-only types
175+ - Use type guards for runtime type narrowing (see ` _types.py ` )
176+ - Follow this general principle for user-facing code: be contravariant in the input type and covariant in the output type
177+ - Add type aliases close to their usage. If widely used, place in ` _types.py ` .
178+
179+ ## Common Patterns
197180
198181** Handling deprecated parameters:**
199182
@@ -221,44 +204,29 @@ def _coerce_to_densities(...):
221204 from ridgeplot._kde import estimate_densities # statsmodels is slow to import
222205```
223206
224- ### Testing Tips
207+ ## Testing Notes
225208
226209- Use ` --no-cov ` flag during development for faster test runs
227- - Run specific tests: ` tox -e pytest -- tests/unit/test_ridgeplot .py -k "test_name " --no-cov `
210+ - Run targeted tests via : ` tox -e pytest -- tests/unit/test_foo .py -k "test_bar " --no-cov `
228211- The ` tests/e2e/artifacts/ ` directory contains expected Plotly Figure JSON for e2e tests
229- - ` conftest.py ` patches ` fig.show() ` to prevent browser windows during tests
230212
231- ### Key Files to Know
213+ ## .cursor Rules
232214
233- | File | Purpose |
234- | ------------------------------------| -----------------------------|
235- | ` src/ridgeplot/_ridgeplot.py ` | Main ` ridgeplot() ` function |
236- | ` src/ridgeplot/_figure_factory.py ` | Figure construction logic |
237- | ` src/ridgeplot/_types.py ` | All type aliases and guards |
238- | ` tests/unit/test_ridgeplot.py ` | Core function tests |
239- | ` cicd_utils/ridgeplot_examples/ ` | Example scripts for docs |
240- | ` tox.ini ` | CI environment definitions |
241- | ` ruff.toml ` | Linting configuration |
215+ Check ` .cursor/rules ` before changing platform or version support. The only
216+ current rule is for adding or dropping Python versions at
217+ ` .cursor/rules/dropping-and-or-adding-support-for-python-versions/RULES.md ` .
242218
243219## CI/CD Pipeline
244220
245- Tests run on GitHub Actions across:
246-
247- - Python versions: 3.10, 3.11, 3.12, 3.13, 3.14
248- - Operating systems: Ubuntu, macOS, Windows
249-
250- Coverage is uploaded to Codecov with:
251-
252- - Overall: 98% minimum
253- - Diff coverage: 100% for new code
221+ GitHub Actions runs tests on Python 3.10–3.14 across Ubuntu, macOS, and Windows.
222+ Codecov minimums are 98% overall and 100% diff coverage for new code.
254223
255224## Notes for AI Assistants
256225
257- 1 . ** Always run tests** after making changes: ` tox -e pytest -- <path> --no-cov `
258- 2 . ** Check types** with: ` tox -e typing `
259- 3 . ** Format code** with: ` pre-commit run ruff-format --all-files `
260- 4 . ** Respect existing patterns** - this is a mature codebase with consistent style
261- 5 . ** Don't add unnecessary abstractions** - keep changes minimal and focused
262- 6 . ** Preserve deprecation warnings** - the library maintains backward compatibility
263- 7 . ** Update docstrings** when changing function signatures
264- 8 . ** Use type guards** for runtime type narrowing instead of assertions
226+ 1 . Run tests after changes when feasible, starting with the smallest relevant
227+ subset.
228+ 2 . Run ` tox -e typing ` if types are touched or errors are likely.
229+ 3 . Run ` pre-commit run ruff-format --all-files ` to format code.
230+ 4 . Preserve deprecation behavior and public API stability.
231+ 5 . Keep changes minimal and aligned with existing patterns.
232+ 6 . Respect existing patterns - this is a mature codebase with consistent style.
0 commit comments