-
Notifications
You must be signed in to change notification settings - Fork 18
[Feature] Add container to encapsulate external axes #422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Fix two unidenfined references in why.rst. 1. ug_apply_norm is a typo I think. 2. ug_mplrc. I'm not sure what it should be. Only by guess.
|
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|
How does this one relate to the feature to mark an axis as external that we just merged? |
|
Good question, I can see how this does not seem that different but it is. This PR fundamentally restructures how Ultraplot integrates external axes classes. Previously, external axes were handled through a mixin-based approach that attempted to modify external classes directly, which proved fragile and caused conflicts with kwargs that external axes didn't understand -- while this is fine for some plots like line and scatters, it can fail for something more complex like ternary plots. The new approach uses a composition-based Importantly, GeoAxes are no longer treated as external — we now explicitly check for the So while both approaches aim to improve compatibility with external packages, they achieve this through different means. The |
|
So while the external marker turns off the tagging feature, the axis being plotting on is fundamentally still an UltraPlotAxis, while this just hosts the external axis within a container. This still allows for nice composition, but uses the external axis for the rest. |
|
Things before sending out review
|
- Increase default shrink factor from 0.75 to 0.95 to make external axes (e.g., ternary plots) larger and more prominent - Change positioning from centered to top-aligned with left offset for better alignment with adjacent Cartesian subplots - Top alignment ensures abc labels and titles align properly across different projection types - Add 5% left offset to better utilize available horizontal space - Update both _shrink_external_for_labels and _ensure_external_fits_within_container methods for consistency This makes ternary and other external axes integrate seamlessly with standard matplotlib subplots, appearing native rather than artificially constrained.
Closes #419
External Axes Integration via Container Pattern
This PR implements robust support for external axes projections (e.g., mpltern's TernaryAxes) in Ultraplot through a container-based architecture. The implementation includes automatic label fitting, performance optimizations, and comprehensive compatibility with Ultraplot's existing features.
Problem Statement
Ultraplot previously struggled with external axes classes that don't inherit from
ultraplot.axes.Axes. Users attempting to use projections like"ternary"from mpltern encountered:Proposed Solution: Container Pattern
Architecture
Instead of wrapping external axes via inheritance (which caused method conflicts), we implement a container pattern:
Key Design Decisions:
CartesianAxes→ Full Ultraplot API supportfig.axes→ Ultraplot internals don't breakCore Components
ExternalAxesContainer (
ultraplot/axes/container.py)Auto-detection (
ultraplot/figure.py)Label Fitting (New Feature)
external_shrink_factorparameterPerformance Optimizations (New Feature)
Changes
Core Implementation
1. Container Architecture
ultraplot/axes/container.py- ExternalAxesContainer classultraplot/axes/__init__.py- Export ExternalAxesContainerultraplot/figure.py- Auto-detect and create containers2. Compatibility Fixes
ultraplot/axes/base.py- SubplotSpec fallback for matplotlib compatibilityultraplot/axes/container.py- Disable autoshare for external axes3. Label Fitting System
_shrink_external_for_labels()- Automatic label space allocationexternal_shrink_factorparameter - Configurable shrinking (default 0.85)4. Performance Optimizations
Tests
Added/Reorganized
ultraplot/tests/test_external_axes_container_integration.py- Pytest tests for containertest_minimal.py→tests/test_external_axes_minimal.pytest_subplotspec_fix.py→tests/test_subplotspec_compatibility.pytest_container_manual.py→tests/test_external_axes_container.py(manual test)Documentation
TBD
Basic Usage
Custom Label Fitting
Multiple Subplots