Skip to content

Fixed empty text bbox drawing. #2710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/matplotlib/backends/backend_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,6 @@ def get_text_width_height_descent(self, s, prop, ismath):
# outside the backend
"""
if rcParams['text.usetex']:
# todo: handle props
size = prop.get_size_in_points()
texmanager = self.get_texmanager()
fontsize = prop.get_size_in_points()
w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
Expand Down Expand Up @@ -248,6 +246,9 @@ def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
x = np.round(x + xd)
y = np.round(y + yd)

if s == '':
return

self._renderer.draw_text_image(Z, x, y, angle, gc)

def get_canvas_width_height(self):
Expand Down
12 changes: 6 additions & 6 deletions lib/matplotlib/bezier.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,10 @@ def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False):

path_iter = path.iter_segments()

ctl_points, command = next(path_iter)
try:
ctl_points, command = next(path_iter)
except StopIteration:
return path, Path(np.zeros((0, 2)))
begin_inside = inside(ctl_points[-2:]) # true if begin point is inside

bezier_path = None
Expand Down Expand Up @@ -280,17 +283,14 @@ def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False):
codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4]
codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]
else:
raise ValueError()
raise ValueError('Unexpected segment length found in path codes.')

verts_left = left[1:]
verts_right = right[:]

#i += 1

if path.codes is None:
path_in = Path(concat([path.vertices[:i], verts_left]))
path_out = Path(concat([verts_right, path.vertices[i:]]))

else:
path_in = Path(concat([path.vertices[:iold], verts_left]),
concat([path.codes[:iold], codes_left]))
Expand Down Expand Up @@ -476,7 +476,7 @@ def make_path_regular(p):
if c is None:
c = np.empty(p.vertices.shape[:1], "i")
c.fill(Path.LINETO)
c[0] = Path.MOVETO
c[0:1] = Path.MOVETO

return Path(p.vertices, c)
else:
Expand Down
5 changes: 5 additions & 0 deletions lib/matplotlib/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -2536,6 +2536,9 @@ def _shrink(self, path, shrinkA, shrinkB):
"""
Shrink the path by fixed size (in points) with shrinkA and shrinkB
"""
if path.vertices.size <= 1:
return path

if shrinkA:
x, y = path.vertices[0]
insideA = inside_circle(x, y, shrinkA)
Expand Down Expand Up @@ -3119,6 +3122,8 @@ def _get_arrow_wedge(self, x0, y0, x1, y1,
return vertices_arrow, codes_arrow, ddx, ddy

def transmute(self, path, mutation_size, linewidth):
if path.vertices.size < 2:
return [path], [False]

head_length, head_width = self.head_length * mutation_size, \
self.head_width * mutation_size
Expand Down
3 changes: 1 addition & 2 deletions lib/matplotlib/tests/test_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
from matplotlib import pyplot as plt
from matplotlib import animation
from matplotlib.testing.noseclasses import KnownFailureTest
from matplotlib.testing.decorators import cleanup
from matplotlib.testing.decorators import CleanupTest
from matplotlib.testing.decorators import CleanupTest, cleanup


WRITER_OUTPUT = dict(ffmpeg='mp4', ffmpeg_file='mp4',
Expand Down
14 changes: 13 additions & 1 deletion lib/matplotlib/tests/test_arrow_patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import six

import matplotlib.pyplot as plt
from matplotlib.testing.decorators import image_comparison
from matplotlib.testing.decorators import image_comparison, cleanup
import matplotlib


Expand All @@ -30,6 +30,18 @@ def test_fancyarrow():
ax.tick_params(labelleft=False, labelbottom=False)


@cleanup
def test_arrow_usetex():
# Passing an empty string to latex triggered an exception, so we ensure
# that null strings are intercepted and drawn appropriately (i.e. don't
# raise an exception).
matplotlib.rcParams['text.usetex'] = True
props = dict(boxstyle='round', edgecolor='red',
facecolor='yellow', alpha=0.5)
plt.annotate(' ', (0, 0), (1, 0), arrowprops=dict(arrowstyle='->'), bbox=props)
plt.draw()


if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
57 changes: 40 additions & 17 deletions lib/matplotlib/tests/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@

import six

import warnings

import mock
import numpy as np

import matplotlib
from matplotlib.testing.decorators import image_comparison, knownfailureif, cleanup
from matplotlib.testing.decorators import image_comparison, cleanup
import matplotlib.text as mtext
import matplotlib.pyplot as plt
import warnings
from nose.tools import with_setup
from matplotlib.backend_bases import RendererBase
from matplotlib.font_manager import FontProperties, findfont


@image_comparison(baseline_images=['font_styles'])
Expand All @@ -21,12 +26,6 @@ def find_matplotlib_font(**kw):
path = findfont(prop, directory=data_path)
return FontProperties(fname=path)

from matplotlib.font_manager import FontProperties, findfont
warnings.filterwarnings('ignore', 'findfont: Font family \[\'Foo\'\] '+ \
'not found. Falling back to .',
UserWarning,
module='matplotlib.font_manager')
fig = plt.figure()
ax = plt.subplot(1, 1, 1)

normalFont = find_matplotlib_font(family="sans-serif",
Expand All @@ -37,13 +36,13 @@ def find_matplotlib_font(**kw):
ax.annotate("Normal Font", (0.1, 0.1), xycoords='axes fraction',
fontproperties=normalFont)

boldFont = find_matplotlib_font(family="Foo",
style="normal",
variant="normal",
weight="bold",
stretch=500,
size=14,
)
with mock.patch('warnings.warn') as warn:
boldFont = find_matplotlib_font(family="Foo", style="normal",
variant="normal", weight="bold",
stretch=500, size=14)
assert warn.call_args[0][0].startswith("findfont: Font family [u'Foo'] "
"not found. Falling back to")

ax.annotate("Bold Font", (0.1, 0.2), xycoords='axes fraction',
fontproperties=boldFont)

Expand Down Expand Up @@ -83,7 +82,6 @@ def find_matplotlib_font(**kw):

@image_comparison(baseline_images=['multiline'])
def test_multiline():
fig = plt.figure()
ax = plt.subplot(1, 1, 1)
ax.set_title("multiline\ntext alignment")

Expand Down Expand Up @@ -226,3 +224,28 @@ def test_set_position():

for a, b in zip(init_pos.min, post_pos.min):
assert a + shift_val == b


def test_empty_string_with_bbox():
# Check that an empty string Text instance can still draw a bbox
# (by calling the _draw_bbox method).
props = dict(boxstyle='round', edgecolor='red',
facecolor='yellow', alpha=0.5)

renderer = RendererBase()
renderer.draw_text = mock.Mock()
fig = plt.figure()

t = mtext.Text(0, 1, '', bbox=props)
t.set_figure(fig)
t._draw_bbox = mock.Mock()

# Do the actual call.
t.draw(renderer)
t._draw_bbox.assert_called_once_with(renderer, 0.0, 1.0)
assert renderer.draw_text.call_count == 1


if __name__ == "__main__":
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
49 changes: 21 additions & 28 deletions lib/matplotlib/tests/test_tightlayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@

import numpy as np

from matplotlib.testing.decorators import image_comparison, knownfailureif
from matplotlib.testing.decorators import image_comparison
import matplotlib.pyplot as plt
from nose.tools import assert_raises
from numpy.testing import assert_array_equal
import matplotlib.gridspec as gridspec


def example_plot(ax, fontsize=12):
ax.plot([1, 2])
ax.locator_params(nbins=3)
ax.set_xlabel('x-label', fontsize=fontsize)
ax.set_ylabel('y-label', fontsize=fontsize)
ax.set_title('Title', fontsize=fontsize)
ax.plot([1, 2])
ax.locator_params(nbins=3)
ax.set_xlabel('x-label', fontsize=fontsize)
ax.set_ylabel('y-label', fontsize=fontsize)
ax.set_title('Title', fontsize=fontsize)


@image_comparison(baseline_images=['tight_layout1'])
def test_tight_layout1():
Expand All @@ -39,10 +40,7 @@ def test_tight_layout2():

@image_comparison(baseline_images=['tight_layout3'])
def test_tight_layout3():
'Test tight_layout for mutiple subplots'

fig = plt.figure()

# Test tight_layout for mutiple subplots
ax1 = plt.subplot(221)
ax2 = plt.subplot(223)
ax3 = plt.subplot(122)
Expand All @@ -57,10 +55,7 @@ def test_tight_layout3():
@image_comparison(baseline_images=['tight_layout4'],
freetype_version=('2.4.5', '2.4.9'))
def test_tight_layout4():
'Test tight_layout for subplot2grid'

fig = plt.figure()

# Test tight_layout for subplot2grid
ax1 = plt.subplot2grid((3, 3), (0, 0))
ax2 = plt.subplot2grid((3, 3), (0, 1), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 0), colspan=2, rowspan=2)
Expand All @@ -76,26 +71,19 @@ def test_tight_layout4():

@image_comparison(baseline_images=['tight_layout5'])
def test_tight_layout5():
'Test tight_layout for image'

fig = plt.figure()

# Test tight_layout for image
ax = plt.subplot(111)
arr = np.arange(100).reshape((10,10))
ax.imshow(arr, interpolation="none")

plt.tight_layout()



@image_comparison(baseline_images=['tight_layout6'])
def test_tight_layout6():
'Test tight_layout for gridspec'

# Test tight_layout for gridspec
fig = plt.figure()

import matplotlib.gridspec as gridspec

gs1 = gridspec.GridSpec(2, 1)
ax1 = fig.add_subplot(gs1[0])
ax2 = fig.add_subplot(gs1[1])
Expand Down Expand Up @@ -130,9 +118,8 @@ def test_tight_layout6():
@image_comparison(baseline_images=['tight_layout7'])
def test_tight_layout7():
# tight layout with left and right titles
fig = plt.figure()
fontsize = 24
ax = fig.add_subplot(111)
ax = plt.subplot(111)
ax.plot([1, 2])
ax.locator_params(nbins=3)
ax.set_xlabel('x-label', fontsize=fontsize)
Expand All @@ -141,10 +128,16 @@ def test_tight_layout7():
ax.set_title('Right Title', loc='right', fontsize=fontsize)
plt.tight_layout()


@image_comparison(baseline_images=['tight_layout8'])
def test_tight_layout8():
'Test automatic use of tight_layout'
# Test automatic use of tight_layout
fig = plt.figure()
fig.set_tight_layout({'pad': .1})
ax = fig.add_subplot(111)
example_plot(ax, fontsize=24)


if __name__ == "__main__":
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
21 changes: 15 additions & 6 deletions lib/matplotlib/texmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,9 @@ def get_basefile(self, tex, fontsize, dpi=None):
s = ''.join([tex, self.get_font_config(), '%f' % fontsize,
self.get_custom_preamble(), str(dpi or '')])
# make sure hash is consistent for all strings, regardless of encoding:
bytes = six.text_type(s).encode('utf-8')
return os.path.join(self.texcache, md5(bytes).hexdigest())
checksum = md5(six.text_type(s).encode('utf-8')).hexdigest()
fname = os.path.join(self.texcache, checksum)
return fname

def get_font_config(self):
"""Reinitializes self if relevant rcParams on have changed."""
Expand Down Expand Up @@ -282,6 +283,12 @@ def make_tex(self, tex, fontsize):
fontcmd = {'sans-serif': r'{\sffamily %s}',
'monospace': r'{\ttfamily %s}'}.get(self.font_family,
r'{\rmfamily %s}')
# Leading and trailing whitespace is ignored anyway (the
# dvipng -T tight call deeper down takes care of that) so convert
# an empty string into a single space character.
if tex.strip() == '':
tex = '\\ '

tex = fontcmd % tex

if rcParams['text.latex.unicode']:
Expand Down Expand Up @@ -333,6 +340,11 @@ def make_tex_preview(self, tex, fontsize):
fontcmd = {'sans-serif': r'{\sffamily %s}',
'monospace': r'{\ttfamily %s}'}.get(self.font_family,
r'{\rmfamily %s}')
# Leading and trailing whitespace is ignored anyway (the
# dvipng -T tight call deeper down takes care of that) so convert
# an empty string into a single space character.
if tex.strip() == '':
tex = '\\ '
tex = fontcmd % tex

if rcParams['text.latex.unicode']:
Expand Down Expand Up @@ -434,7 +446,7 @@ def make_dvi_preview(self, tex, fontsize):
"""
generates a dvi file containing latex's layout of tex
string. It calls make_tex_preview() method and store the size
information (width, height, descent) in a separte file.
information (width, height, descent) in a separate file.

returns the file name
"""
Expand Down Expand Up @@ -644,9 +656,6 @@ def get_text_width_height_descent(self, tex, fontsize, renderer=None):
"""
return width, heigth and descent of the text.
"""
if tex.strip() == '':
return 0, 0, 0

if renderer:
dpi_fraction = renderer.points_to_pixels(1.)
else:
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy