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

Skip to content

Commit 2d605c6

Browse files
committed
BUGFIX: Line2D.get_window_extents more accurate
1 parent 7d84966 commit 2d605c6

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