Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Description
Bug summary
Thedocumentation forsecondary_[xy]axis
claims to accept aTransform
for thefunctions
parameter.
However, the checks inset_functions
do not acceptTransform
:
matplotlib/lib/matplotlib/axes/_secondary_axes.py
Lines 147 to 158 in3f4d4c1
if (isinstance(functions,tuple)andlen(functions)==2and | |
callable(functions[0])andcallable(functions[1])): | |
# make an arbitrary convert from a two-tuple of functions | |
# forward and inverse. | |
self._functions=functions | |
eliffunctionsisNone: | |
self._functions= (lambdax:x,lambdax:x) | |
else: | |
raiseValueError('functions argument of secondary axes ' | |
'must be a two-tuple of callable functions ' | |
'with the first function being the transform ' | |
'and the second being the inverse') |
and any usage of the internal attribute seems to assume a tuple of callables:
matplotlib/lib/matplotlib/axes/_secondary_axes.py
Lines 193 to 194 in3f4d4c1
set_scale('functionlog'ifpscale=='log'else'function', | |
functions=self._functions[::-1]) |
lims=self._functions[0](np.array(lims)) |
Both this documentation and the checks have been in the code since it was added in#11859.
Code for reproduction
importmatplotlib.pyplotaspltfrommatplotlib.transformsimportIdentityTransformfig,ax=plt.subplots()secax=ax.secondary_xaxis('top',functions=IdentityTransform)# OR:secax=ax.secondary_xaxis('top',functions=IdentityTransform())# OR:secax=ax.secondary_xaxis('top',functions=(IdentityTransform,IdentityTransform))# OR:secax=ax.secondary_xaxis('top',functions=(IdentityTransform(),IdentityTransform()))
Actual outcome
With a single transform (class or object),or a tuple of transform objects, it fails in the setter:
Traceback (most recent call last): File"galleries/examples/subplots_axes_and_figures/secondary_axis.py", line40, in<module> secax= ax.secondary_xaxis('top',functions=IdentityTransform) File"lib/matplotlib/axes/_axes.py", line586, insecondary_xaxis secondary_ax= SecondaryAxis(self,'x', location, functions, File"lib/matplotlib/axes/_secondary_axes.py", line42, in__init__self.set_functions(functions) File"lib/matplotlib/axes/_secondary_axes.py", line155, inset_functionsraiseValueError('functions argument of secondary axes'ValueError:functions argument of secondary axes must be a two-tuple of callable functions with the first function being the transform and the second being the inverse
With a tuple of transform classes, the setter allows it, but it fails when drawing:
Traceback (most recent call last): File "lib/matplotlib/backends/backend_qt.py", line 461, in _draw_idle self.draw() File "lib/matplotlib/backends/backend_agg.py", line 401, in draw self.figure.draw(self.renderer) File "lib/matplotlib/artist.py", line 95, in draw_wrapper result = draw(artist, renderer, *args, **kwargs) File "lib/matplotlib/artist.py", line 72, in draw_wrapper return draw(artist, renderer) File "lib/matplotlib/figure.py", line 3115, in draw artists = self._get_draw_artists(renderer) File "lib/matplotlib/figure.py", line 225, in _get_draw_artists child.apply_aspect( File "lib/matplotlib/axes/_secondary_axes.py", line 120, in apply_aspect self._set_lims() File "lib/matplotlib/axes/_secondary_axes.py", line 216, in _set_lims lims = self._functions[0](np.array(lims)) File "lib/matplotlib/transforms.py", line 1759, in __init__ super().__init__(*args, **kwargs) File "lib/matplotlib/transforms.py", line 125, in __init__ self._shorthand_name = shorthand_name or ''ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Expected outcome
At least one of the options works, or it should not be documented as accepted.
Additional information
I noticed this oddity in the types while reviewing#25224, but not sure what we intend here.
Operating system
No response
Matplotlib Version
Matplotlib Backend
No response
Python version
No response
Jupyter version
No response
Installation
git checkout