Skip to content

Commit 812f938

Browse files
committed
BUGFIX: Line2D.get_window_extents more accurate
1 parent 0a92c2f commit 812f938

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

lib/matplotlib/lines.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -613,15 +613,46 @@ def set_picker(self, p):
613613
self._picker = p
614614

615615
def get_window_extent(self, renderer):
616-
bbox = Bbox([[0, 0], [0, 0]])
617-
trans_data_to_xy = self.get_transform().transform
618-
bbox.update_from_data_xy(trans_data_to_xy(self.get_xydata()),
619-
ignore=True)
620-
# correct for marker size, if any
616+
"""
617+
Get bbox of Line2D in pixel space.
618+
619+
Notes
620+
-----
621+
Both the (stroked) line itself or any markers that have been placed
622+
every ``markevery`` vertices along the line could be responsible for a
623+
`Line2D`'s extents.
624+
"""
625+
# marker contribution
621626
if self._marker:
622-
ms = (self._markersize / 72.0 * self.figure.dpi) * 0.5
623-
bbox = bbox.padded(ms)
624-
return bbox
627+
pts_box = self._marker.get_drawn_bbox(
628+
self._markersize, self._markeredgewidth)
629+
pix_box = pts_box.transformed(
630+
Affine2D().scale(self.figure.dpi / 72.0))
631+
else:
632+
pix_box = Bbox([[0, 0], [0, 0]])
633+
marker_bbox = Bbox.null()
634+
trans_data_to_xy = self.get_transform().transform
635+
xy = trans_data_to_xy(self.get_xydata())
636+
if self._markevery:
637+
xy = xy[::self._markevery]
638+
bottom_left = xy + np.array([pix_box.x0, pix_box.y0])
639+
marker_bbox.update_from_data_xy(bottom_left, ignore=True)
640+
top_right = xy + np.array([pix_box.x1, pix_box.y1])
641+
marker_bbox.update_from_data_xy(top_right, ignore=False)
642+
643+
# line's contribution
644+
if self.is_dashed():
645+
cap = self._dashcapstyle
646+
join = self._dashjoinstyle
647+
else:
648+
cap = self._solidcapstyle
649+
join = self._solidjoinstyle
650+
line_bbox = Bbox.null()
651+
path, affine = (self._get_transformed_path()
652+
.get_transformed_path_and_affine())
653+
lw = self.get_linewidth() / 72.0 * self.figure.dpi
654+
path_bbox = path.get_stroked_extents(lw, affine, join, cap)
655+
return Bbox.union([path_bbox, marker_bbox])
625656

626657
@Artist.axes.setter
627658
def axes(self, ax):

lib/matplotlib/markers.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132

133133
from . import cbook, rcParams
134134
from .path import Path
135-
from .transforms import IdentityTransform, Affine2D
135+
from .transforms import IdentityTransform, Affine2D, Bbox
136136

137137
# special-purpose marker identifiers:
138138
(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
@@ -869,3 +869,29 @@ def _set_x_filled(self):
869869
self._alt_transform = Affine2D().translate(-0.5, -0.5)
870870
self._transform.rotate_deg(rotate)
871871
self._alt_transform.rotate_deg(rotate_alt)
872+
873+
def get_drawn_bbox(self, markersize, markeredgewidth, **kwargs):
874+
"""
875+
Get size of bbox of marker directly from its path.
876+
877+
Parameters
878+
----------
879+
markersize : float
880+
"Size" of the marker, in points.
881+
markeredgewidth : float, optional, default: 0
882+
Width, in points, of the stroke used to create the marker's edge.
883+
**kwargs
884+
Forwarded to `~.path.Path.iter_angles`.
885+
886+
Returns
887+
-------
888+
bbox : matplotlib.transforms.Bbox
889+
The extents of the marker including its edge (in points) if it were
890+
centered at (0,0).
891+
"""
892+
if np.isclose(markersize, 0):
893+
return Bbox([[0, 0], [0, 0]])
894+
scale = Affine2D().scale(markersize)
895+
transform = scale + self._transform
896+
return self._path.get_stroked_extents(markeredgewidth, transform,
897+
self._joinstyle, self._capstyle)

0 commit comments

Comments
 (0)
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