Skip to content

Commit

Permalink
Merge pull request matplotlib#4843 from tacaswell/REV_coord_wrapping
Browse files Browse the repository at this point in the history
Rev coord wrapping
  • Loading branch information
dopplershift committed Aug 6, 2015
2 parents d69c7ac + 2a23b7c commit 4b25853
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 180 deletions.
9 changes: 9 additions & 0 deletions doc/api/api_changes/2015-07-30_annotation_wrap.rst
@@ -0,0 +1,9 @@
No annotation coordinates wrap
``````````````````````````````

In #2351 for 1.4.0 the behavior of ['axes points', 'axes pixel',
'figure points', 'figure pixel'] as coordinates was change to
no longer wrap for negative values. In 1.4.3 this change was
reverted for 'axes points' and 'axes pixel' and in addition caused
'axes fraction' to wrap. For 1.5 the behavior has been reverted to
as it was in 1.4.0-1.4.2, no wrapping for any type of coordinate.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
216 changes: 53 additions & 163 deletions lib/matplotlib/tests/test_text.py
Expand Up @@ -313,169 +313,59 @@ def test_bbox_clipping():
t.set_bbox({"boxstyle": "round, pad=0.1"})


@image_comparison(baseline_images=['annotation_negative_coords'],
@image_comparison(baseline_images=['annotation_negative_ax_coords'],
extensions=['png'])
def test_annotation_negative_coords():
fig = plt.figure()
ax = plt.subplot(1, 1, 1)

ax.annotate("+fpt", (15, 40), xycoords="figure points")
ax.annotate("+fpx", (25, 30), xycoords="figure pixels")
ax.annotate("+apt", (35, 20), xycoords="axes points")
ax.annotate("+apx", (45, 10), xycoords="axes pixels")

ax.annotate("-fpt", (-55, -40), xycoords="figure points")
ax.annotate("-fpx", (-45, -30), xycoords="figure pixels")
ax.annotate("-apt", (-35, -20), xycoords="axes points")
ax.annotate("-apx", (-25, -10), xycoords="axes pixels")


@cleanup
def test_text_annotation_get_window_extent():
figure = Figure(dpi=100)
renderer = RendererAgg(200, 200, 100)

# Only text annotation
annotation = Annotation('test', xy=(0, 0))
annotation.set_figure(figure)

text = Text(text='test', x=0, y=0)
text.set_figure(figure)

bbox = annotation.get_window_extent(renderer=renderer)

text_bbox = text.get_window_extent(renderer=renderer)
eq_(bbox.width, text_bbox.width)
eq_(bbox.height, text_bbox.height)

_, _, d = renderer.get_text_width_height_descent(
'text', annotation._fontproperties, ismath=False)
_, _, lp_d = renderer.get_text_width_height_descent(
'lp', annotation._fontproperties, ismath=False)
below_line = max(d, lp_d)

# These numbers are specific to the current implementation of Text
points = bbox.get_points()
eq_(points[0, 0], 0.0)
eq_(points[1, 0], text_bbox.width)
eq_(points[0, 1], -below_line)
eq_(points[1, 1], text_bbox.height - below_line)


@cleanup
def test_text_with_arrow_annotation_get_window_extent():
headwidth = 21
fig, ax = plt.subplots(dpi=100)
txt = ax.text(s='test', x=0, y=0)
ann = ax.annotate(
'test',
xy=(0.0, 50.0),
xytext=(50.0, 50.0), xycoords='figure pixels',
arrowprops={
'facecolor': 'black', 'width': 2,
'headwidth': headwidth, 'shrink': 0.0})

plt.draw()
renderer = fig.canvas.renderer
# bounding box of text
text_bbox = txt.get_window_extent(renderer=renderer)
# bounding box of annotation (text + arrow)
bbox = ann.get_window_extent(renderer=renderer)
# bounding box of arrow
arrow_bbox = ann.arrow_patch.get_window_extent(renderer)
# bounding box of annotation text
ann_txt_bbox = Text.get_window_extent(ann)

# make sure annotation width is 50 px wider than
# just the text
eq_(bbox.width, text_bbox.width + 50.0)
# make sure the annotation text bounding box is same size
# as the bounding box of the same string as a Text object
eq_(ann_txt_bbox.height, text_bbox.height)
eq_(ann_txt_bbox.width, text_bbox.width)
# compute the expected bounding box of arrow + text
expected_bbox = Bbox.union([ann_txt_bbox, arrow_bbox])
assert_almost_equal(bbox.height, expected_bbox.height)


@cleanup
def test_arrow_annotation_get_window_extent():
dpi = 100
dots_per_point = dpi / 72
figure = Figure(dpi=dpi)
figure.set_figwidth(2.0)
figure.set_figheight(2.0)
renderer = RendererAgg(200, 200, 100)

# Text annotation with arrow; arrow dimensions are in points
annotation = Annotation(
'', xy=(0.0, 50.0), xytext=(50.0, 50.0), xycoords='figure pixels',
arrowprops={
'facecolor': 'black', 'width': 8, 'headwidth': 10, 'shrink': 0.0})
annotation.set_figure(figure)
annotation.draw(renderer)

bbox = annotation.get_window_extent()
points = bbox.get_points()

eq_(bbox.width, 50.0)
assert_almost_equal(bbox.height, 10.0 * dots_per_point)
eq_(points[0, 0], 0.0)
eq_(points[0, 1], 50.0 - 5 * dots_per_point)


@cleanup
def test_empty_annotation_get_window_extent():
figure = Figure(dpi=100)
figure.set_figwidth(2.0)
figure.set_figheight(2.0)
renderer = RendererAgg(200, 200, 100)

# Text annotation with arrow
annotation = Annotation(
'', xy=(0.0, 50.0), xytext=(0.0, 50.0), xycoords='figure pixels')
annotation.set_figure(figure)
annotation.draw(renderer)

bbox = annotation.get_window_extent()
points = bbox.get_points()

eq_(points[0, 0], 0.0)
eq_(points[1, 0], 0.0)
eq_(points[1, 1], 50.0)
eq_(points[0, 1], 50.0)

def test_annotation_negative_ax_coords():
fig, ax = plt.subplots()

@image_comparison(baseline_images=['basictext_wrap'],
extensions=['png'])
def test_basic_wrap():
fig = plt.figure()
plt.axis([0, 10, 0, 10])
t = "This is a really long string that I'd rather have wrapped so that" \
" it doesn't go outside of the figure, but if it's long enough it" \
" will go off the top or bottom!"
plt.text(4, 1, t, ha='left', rotation=15, wrap=True)
plt.text(6, 5, t, ha='left', rotation=15, wrap=True)
plt.text(5, 5, t, ha='right', rotation=-15, wrap=True)
plt.text(5, 10, t, fontsize=18, style='oblique', ha='center',
va='top', wrap=True)
plt.text(3, 4, t, family='serif', style='italic', ha='right', wrap=True)
plt.text(-1, 0, t, ha='left', rotation=-15, wrap=True)


@image_comparison(baseline_images=['fonttext_wrap'],
ax.annotate('+ pts',
xytext=[30, 20], textcoords='axes points',
xy=[30, 20], xycoords='axes points', fontsize=32)
ax.annotate('- pts',
xytext=[30, -20], textcoords='axes points',
xy=[30, -20], xycoords='axes points', fontsize=32,
va='top')
ax.annotate('+ frac',
xytext=[0.75, 0.05], textcoords='axes fraction',
xy=[0.75, 0.05], xycoords='axes fraction', fontsize=32)
ax.annotate('- frac',
xytext=[0.75, -0.05], textcoords='axes fraction',
xy=[0.75, -0.05], xycoords='axes fraction', fontsize=32,
va='top')

ax.annotate('+ pixels',
xytext=[160, 25], textcoords='axes pixels',
xy=[160, 25], xycoords='axes pixels', fontsize=32)
ax.annotate('- pixels',
xytext=[160, -25], textcoords='axes pixels',
xy=[160, -25], xycoords='axes pixels', fontsize=32,
va='top')


@image_comparison(baseline_images=['annotation_negative_fig_coords'],
extensions=['png'])
def test_font_wrap():
fig = plt.figure()
plt.axis([0, 10, 0, 10])
t = "This is a really long string that I'd rather have wrapped so that" \
" it doesn't go outside of the figure, but if it's long enough it" \
" will go off the top or bottom!"
plt.text(4, -1, t, fontsize=18, family='serif', ha='left', rotation=15,
wrap=True)
plt.text(6, 5, t, family='sans serif', ha='left', rotation=15, wrap=True)
plt.text(5, 5, t, weight='light', ha='right', rotation=-15, wrap=True)
plt.text(5, 10, t, weight='heavy', ha='center', va='top', wrap=True)
plt.text(3, 4, t, family='monospace', ha='right', wrap=True)
plt.text(-1, 0, t, fontsize=14, style='italic', ha='left', rotation=-15,
wrap=True)
def test_annotation_negative_fig_coords():
fig, ax = plt.subplots()

ax.annotate('+ pts',
xytext=[10, 120], textcoords='figure points',
xy=[10, 120], xycoords='figure points', fontsize=32)
ax.annotate('- pts',
xytext=[-10, 180], textcoords='figure points',
xy=[-10, 180], xycoords='figure points', fontsize=32,
va='top')
ax.annotate('+ frac',
xytext=[0.05, 0.55], textcoords='figure fraction',
xy=[0.05, 0.55], xycoords='figure fraction', fontsize=32)
ax.annotate('- frac',
xytext=[-0.05, 0.5], textcoords='figure fraction',
xy=[-0.05, 0.5], xycoords='figure fraction', fontsize=32,
va='top')

ax.annotate('+ pixels',
xytext=[50, 50], textcoords='figure pixels',
xy=[50, 50], xycoords='figure pixels', fontsize=32)
ax.annotate('- pixels',
xytext=[-50, 100], textcoords='figure pixels',
xy=[-50, 100], xycoords='figure pixels', fontsize=32,
va='top')
23 changes: 6 additions & 17 deletions lib/matplotlib/text.py
Expand Up @@ -1704,17 +1704,17 @@ def _get_xy(self, renderer, x, y, s):
if s2 == 'data':
y = float(self.convert_yunits(y))

tr = self._get_xy_transform(renderer, (x, y), s)
tr = self._get_xy_transform(renderer, s)
x1, y1 = tr.transform_point((x, y))
return x1, y1

def _get_xy_transform(self, renderer, xy, s):
def _get_xy_transform(self, renderer, s):

if isinstance(s, tuple):
s1, s2 = s
from matplotlib.transforms import blended_transform_factory
tr1 = self._get_xy_transform(renderer, xy, s1)
tr2 = self._get_xy_transform(renderer, xy, s2)
tr1 = self._get_xy_transform(renderer, s1)
tr2 = self._get_xy_transform(renderer, s2)
tr = blended_transform_factory(tr1, tr2)
return tr

Expand Down Expand Up @@ -1763,17 +1763,7 @@ def _get_xy_transform(self, renderer, xy, s):
# bbox0 = self._get_bbox(renderer, bbox)

if bbox0 is not None:
x, y = xy
bounds = bbox0.extents
if x < 0:
x0 = bounds[2]
else:
x0 = bounds[0]
if y < 0:
y0 = bounds[3]
else:
y0 = bounds[1]
xy0 = (x0, y0)
xy0 = bbox0.bounds[:2]
elif bbox_name == "offset":
xy0 = self._get_ref_xy(renderer)

Expand Down Expand Up @@ -2120,8 +2110,7 @@ def _update_position_xytext(self, renderer, xy_pixel):
patch.
"""
# generate transformation,
self.set_transform(self._get_xy_transform(
renderer, self.xy, self.anncoords))
self.set_transform(self._get_xy_transform(renderer, self.anncoords))

ox0, oy0 = self._get_xy_display()
ox1, oy1 = xy_pixel
Expand Down

0 comments on commit 4b25853

Please sign in to comment.