8000 Merge pull request #26466 from anntzer/coordcopy · matplotlib/matplotlib@2cbb3e0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2cbb3e0

Browse files
authored
Merge pull request #26466 from anntzer/coordcopy
Make annotate/OffsetFrom unaffected by later mutation of coordinates.
2 parents 3dd06a4 + 8f1141b commit 2cbb3e0

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

lib/matplotlib/tests/test_text.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import matplotlib.transforms as mtransforms
1717
from matplotlib.testing.decorators import check_figures_equal, image_comparison
1818
from matplotlib.testing._markers import needs_usetex
19-
from matplotlib.text import Text, Annotation
19+
from matplotlib.text import Text, Annotation, OffsetFrom
2020

2121
pyparsing_version = parse_version(pyparsing.__version__)
2222

@@ -988,3 +988,19 @@ def test_text_math_antialiased_off_default_vs_manual(fig_test, fig_ref):
988988

989989
mpl.rcParams['text.antialiased'] = False
990990
fig_ref.text(0.5, 0.5, r"OutsideMath $I\'m \sqrt{2}$")
991+
992+
993+
@check_figures_equal(extensions=["png"])
994+
def test_annotate_and_offsetfrom_copy_input(fig_test, fig_ref):
995+
# Both approaches place the text (10, 0) pixels away from the center of the line.
996+
ax = fig_test.add_subplot()
997+
l, = ax.plot([0, 2], [0, 2])
998+
of_xy = np.array([.5, .5])
999+
ax.annotate("foo", textcoords=OffsetFrom(l, of_xy), xytext=(10, 0),
1000+
xy=(0, 0)) # xy is unused.
1001+
of_xy[:] = 1
1002+
ax = fig_ref.add_subplot()
1003+
l, = ax.plot([0, 2], [0, 2])
1004+
an_xy = np.array([.5, .5])
1005+
ax.annotate("foo", xy=an_xy, xycoords=l, xytext=(10, 0), textcoords="offset points")
1006+
an_xy[:] = 2

lib/matplotlib/text.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,8 @@ def __init__(self, artist, ref_coord, unit="points"):
13891389
The screen units to use (pixels or points) for the offset input.
13901390
"""
13911391
self._artist = artist
1392-
self._ref_coord = ref_coord
1392+
x, y = ref_coord # Make copy when ref_coord is an array (and check the shape).
1393+
self._ref_coord = x, y
13931394
self.set_unit(unit)
13941395

13951396
def set_unit(self, unit):
@@ -1407,13 +1408,6 @@ def get_unit(self):
14071408
"""Return the unit for input to the transform used by ``__call__``."""
14081409
return self._unit
14091410

1410-
def _get_scale(self, renderer):
1411-
unit = self.get_unit()
1412-
if unit == "pixels":
1413-
return 1.
1414-
else:
1415-
return renderer.points_to_pixels(1.)
1416-
14171411
def __call__(self, renderer):
14181412
"""
14191413
Return the offset transform.
@@ -1443,11 +1437,8 @@ def __call__(self, renderer):
14431437
x, y = self._artist.transform(self._ref_coord)
14441438
else:
14451439
_api.check_isinstance((Artist, BboxBase, Transform), artist=self._artist)
1446-
1447-
sc = self._get_scale(renderer)
1448-
tr = Affine2D().scale(sc).translate(x, y)
1449-
1450-
return tr
1440+
scale = 1 if self._unit == "pixels" else renderer.points_to_pixels(1)
1441+
return Affine2D().scale(scale).translate(x, y)
14511442

14521443

14531444
class _AnnotationBase:
@@ -1456,7 +1447,8 @@ def __init__(self,
14561447
xycoords='data',
14571448
annotation_clip=None):
14581449

1459-
self.xy = xy
1450+
x, y = xy # Make copy when xy is an array (and check the shape).
1451+
self.xy = x, y
14601452
self.xycoords = xycoords
14611453
self.set_annotation_clip(annotation_clip)
14621454

0 commit comments

Comments
 (0)
0