8000 BUGFIX: Line2D.get_window_extents more accurate · matplotlib/matplotlib@543929b · GitHub
[go: up one dir, main page]

Skip to content

Commit 543929b

Browse files
committed
BUGFIX: Line2D.get_window_extents more accurate
1 parent 265caec commit 543929b

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
@@ -605,15 +605,46 @@ def set_picker(self, p):
605605
self._picker = p
606606

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

618649
@Artist.axes.setter
619650
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,
@@ -908,3 +908,29 @@ def _set_x_filled(self):
908908
self._alt_transform = Affine2D().translate(-0.5, -0.5)
909909
self._transform.rotate_deg(rotate)
910910
self._alt_transform.rotate_deg(rotate_alt)
911+
912+
def get_drawn_bbox(self, markersize, markeredgewidth, **kwargs):
913+
"""
914+
Get size of bbox of marker directly from its path.
915+
916+
Parameters
917+
----------
918+
markersize : float
919+
"Size" of the marker, in points.
920+
markeredgewidth : float, optional, default: 0
921+
Width, in points, of the stroke used to create the marker's edge.
922+
**kwargs
923+
Forwarded to `~.path.Path.iter_angles`.
924+
925+
Returns
926+
-------
927+
bbox : matplotlib.transforms.Bbox
928+
The extents of the marker including its edge (in points) if it were
929+
centered at (0,0).
930+
"""
931+
if np.isclose(markersize, 0):
932+
return Bbox([[0, 0], [0, 0]])
933+
scale = Affine2D().scale(markersize)
934+
transform = scale + self._transform
935+
return self._path.get_stroked_extents(markeredgewidth, transform,
936+
self._joinstyle, self._capstyle)

0 commit comments

Comments
 (0)
0