From 82ec83808634b2aa6ce58a925b55be5e19df87fc Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sat, 23 Jan 2021 20:08:26 +0100 Subject: [PATCH] Fix half-filled markers protrusion. Don't let the miter joins protrude by manually cropping them. This is currently only implemented for diamond, but others should work "similarly". However, this reveals a bug(?) in Agg's handling of miter with close corners, which does not handle that case correctly. (pdf, ps, svg, and cairo all handle it fine). Also don't forget a closepoly on half-filled squares. --- lib/matplotlib/markers.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/matplotlib/markers.py b/lib/matplotlib/markers.py index be1f81ca3b1e..a2813cf3f839 100644 --- a/lib/matplotlib/markers.py +++ b/lib/matplotlib/markers.py @@ -519,15 +519,13 @@ def _set_square(self): if not self._half_fill(): self._path = Path.unit_rectangle() else: - # Build a bottom filled square out of two rectangles, one filled. - self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 0.5], - [0.0, 0.5], [0.0, 0.0]]) - self._alt_path = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0], - [0.0, 1.0], [0.0, 0.5]]) + self._path = self._alt_path = Path( # Half-square. + [[0.0, 0.0], [1.0, 0.0], [1.0, 0.5], [0.0, 0.5], [0.0, 0.0]], + closed=True) fs = self.get_fillstyle() rotate = {'bottom': 0, 'right': 90, 'top': 180, 'left': 270}[fs] self._transform.rotate_deg(rotate) - self._alt_transform = self._transform + self._alt_transform = self._transform.frozen().rotate_deg(180) self._joinstyle = JoinStyle.miter @@ -537,17 +535,21 @@ def _set_diamond(self): if not self._half_fill(): self._path = Path.unit_rectangle() else: - self._path = Path([[0, 0], [1, 0], [1, 1], [0, 0]]) - self._alt_path = Path([[0, 0], [0, 1], [1, 1], [0, 0]]) + eps = 1e-3 # Don't let the miter joins protrude. + self._path = self._alt_path = Path( + [[eps, eps], [eps, 0], [1, 0], [1, 1-eps], [1-eps, 1-eps], + [eps, eps]], closed=True) fs = self.get_fillstyle() - rotate = {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs] + rotate = {'bottom': 0, 'right': 90, 'top': 180, 'left': 270}[fs] self._transform.rotate_deg(rotate) - self._alt_transform = self._transform - self._joinstyle = JoinStyle.miter + self._alt_transform = self._transform.frozen().rotate_deg(180) + self._joinstyle = 'miter' def _set_thin_diamond(self): self._set_diamond() self._transform.scale(0.6, 1.0) + if self._alt_transform: + self._alt_transform.scale(0.6, 1.0) def _set_pentagon(self): self._transform = Affine2D().scale(0.5)