Skip to content
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

Fix bugs in legend positioning with loc='best' #1640

Merged
merged 10 commits into from Feb 19, 2013
2 changes: 1 addition & 1 deletion doc/devel/testing.rst
Expand Up @@ -73,7 +73,7 @@ example, here is a test from :mod:`matplotlib.tests.test_basic`::
Nose determines which functions are tests by searching for functions
beginning with "test" in their name.

If the test as side effects that need to be cleaned up, such as
If the test has side effects that need to be cleaned up, such as
creating figures using the pyplot interface, use the ``@cleanup``
decorator::

Expand Down
27 changes: 21 additions & 6 deletions lib/matplotlib/legend.py
Expand Up @@ -108,7 +108,7 @@ class Legend(Artist):
'upper center' : 9,
'center' : 10,

loc can be a tuple of the noramilzed coordinate values with
loc can be a tuple of the normalized coordinate values with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

respect its parent.

"""
Expand Down Expand Up @@ -729,7 +729,6 @@ def _auto_legend_data(self):
assert self.isaxes

ax = self.parent
vertices = []
bboxes = []
lines = []

Expand All @@ -750,6 +749,11 @@ def _auto_legend_data(self):
transform = handle.get_transform()
bboxes.append(handle.get_path().get_extents(transform))

try:
vertices = np.concatenate([l.vertices for l in lines])
except ValueError:
vertices = np.array([])

return [vertices, bboxes, lines]

def draw_frame(self, b):
Expand Down Expand Up @@ -915,20 +919,31 @@ def _find_best_position(self, width, height, renderer, consider=None):
verts, bboxes, lines = self._auto_legend_data()

bbox = Bbox.from_bounds(0, 0, width, height)
consider = [self._get_anchored_bbox(x, bbox, self.get_bbox_to_anchor(),
renderer)
for x
in range(1, len(self.codes))]
if consider is None:
consider = [self._get_anchored_bbox(x, bbox,
self.get_bbox_to_anchor(),
renderer)
for x in range(1, len(self.codes))]

#tx, ty = self.legendPatch.get_x(), self.legendPatch.get_y()

candidates = []
for l, b in consider:
legendBox = Bbox.from_bounds(l, b, width, height)
badness = 0
# XXX TODO: If markers are present, it would be good to
# take their into account when checking vertex overlaps in
# the next line.
badness = legendBox.count_contains(verts)
badness += legendBox.count_overlaps(bboxes)
for line in lines:
# FIXME: the following line is ill-suited for lines
# that 'spiral' around the center, because the bbox
# may intersect with the legend even if the line
# itself doesn't. One solution would be to break up
# the line into its straight-segment components, but
# this may (or may not) result in a significant
# slowdown if lines with many vertices are present.
if line.intersects_bbox(legendBox):
badness += 1

Expand Down
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.