Skip to content

Fix crash with custom tick formatters/locators and Est()#3912

Open
Mr-Neutr0n wants to merge 1 commit into
mwaskom:masterfrom
Mr-Neutr0n:fix/pseudo-axis-shared-locator-3585
Open

Fix crash with custom tick formatters/locators and Est()#3912
Mr-Neutr0n wants to merge 1 commit into
mwaskom:masterfrom
Mr-Neutr0n:fix/pseudo-axis-shared-locator-3585

Conversation

@Mr-Neutr0n

Copy link
Copy Markdown

Summary

Fixes #3585

When using so.Est() with custom matplotlib formatters (e.g. PercentFormatter) or locators (e.g. LogLocator), the plot crashes with AttributeError: 'PseudoAxis' object has no attribute '_view_interval' (or '_get_shared_axis').

The root cause is that _get_scale() returns locator/formatter instances that are shared across multiple calls to _setup(). When a scale is set up for derived coordinate variables like ymin/ymax (which happens with Est()), a PseudoAxis is created internally, and set_default_locators_and_formatters overwrites the shared locator's axis reference to point at this PseudoAxis. The main variable's scale then tries to use the locator, which now references a PseudoAxis that lacks attributes like _view_interval.

Changes

  • Deepcopy locators and formatter in _get_scale() so each scale setup gets independent instances that won't interfere with each other
  • Initialize _view_interval in PseudoAxis.__init__ as a defensive measure, matching the existing pattern for _data_interval

Test plan

  • Verified fix with both reproduction cases from the issue (PercentFormatter and LogLocator with Est())
  • Full test suite passes (2361 passed, 14 skipped, 6 xfailed)

When using so.Est() with custom formatters like PercentFormatter or
locators like LogLocator, the scale setup for derived coordinate
variables (ymin/ymax) would share the same locator/formatter instances
as the main variable's scale. This caused the locator's internal axis
reference to be overwritten to point at a PseudoAxis, which lacked
the _view_interval attribute and other methods that matplotlib expects.

Fix this by deepcopying locators and formatters in _get_scale() so each
scale gets independent instances, and also initialize _view_interval in
PseudoAxis.__init__ as a defensive measure.

Fixes mwaskom#3585
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

so.Est() + tick label formatter => 'PseudoAxis' object has no attribute '_view_interval'

1 participant