Description
Bug summary
When an Axes is initialized using a Bbox object, changing the Axes' position (for example, via ax.set_position
) will also alter the original Bbox object. This is because the Axes retains a reference to the Bbox object rather than creating a separate copy during initialization.
Code for reproduction
import matplotlib.pyplot as plt
from matplotlib.transforms import Bbox
bbox = Bbox([[0.1, 0.1], [0.9, 0.9]])
fig = plt.figure()
ax = fig.add_axes(bbox)
ax.set_position([0.25, 0.25, 0.5, 0.5])
print(bbox)
print(id(bbox), id(ax._position))
Actual outcome
Bbox(x0=0.25, y0=0.25, x1=0.75, y1=0.75)
140507022809120 140507022809120
Expected outcome
Bbox(x0=0.1, y0=0.1, x1=0.9, y1=0.9)
... ... # Two different IDs
Additional information
This issue originates from _AxesBase.__init__
,
matplotlib/lib/matplotlib/axes/_base.py
Lines 650 to 651 in 8d64f03
where args[0]
is directly assigned to self._position
without making a copy.
I don't know if this is a bug or a feature, but it does break encapsulation.
Additionally, some other initialization methods (for example, Bbox.__init__
) that use np.asarray
instead of np.array
can cause similar issues.
Operating system
No response
Matplotlib Version
3.10.0
Matplotlib Backend
No response
Python version
No response
Jupyter version
No response
Installation
None