Skip to content

Commit 0810bfa

Browse files
committed
Shorten/make more consistent the half-filled marker definitions.
- Use dict lookups for fillstyle. - When possible, prefer defining `path` and `alt_path` to the same path and just make `alt_transform` the 180°-rotated version of `transform`. (This is consistent with what's already being done for "circle" and "octagon".) Doing so requires redefining the half-X and half-plus marker paths to not require a (-.5, -.5) translation but that actually makes the path symmetries more apparent.
1 parent 1eef019 commit 0810bfa

File tree

1 file changed

+58
-148
lines changed

1 file changed

+58
-148
lines changed

lib/matplotlib/markers.py

+58-148
Original file line numberDiff line numberDiff line change
@@ -424,22 +424,13 @@ def _half_fill(self):
424424
def _set_circle(self, reduction=1.0):
425425
self._transform = Affine2D().scale(0.5 * reduction)
426426
self._snap_threshold = np.inf
427-
fs = self.get_fillstyle()
428427
if not self._half_fill():
429428
self._path = Path.unit_circle()
430429
else:
431-
# build a right-half circle
432-
if fs == 'bottom':
433-
rotate = 270.
434-
elif fs == 'top':
435-
rotate = 90.
436-
elif fs == 'left':
437-
rotate = 180.
438-
else:
439-
rotate = 0.
440-
441430
self._path = self._alt_path = Path.unit_circle_righthalf()
442-
self._transform.rotate_deg(rotate)
431+
fs = self.get_fillstyle()
432+
self._transform.rotate_deg(
433+
{'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs])
443434
self._alt_transform = self._transform.frozen().rotate_deg(180.)
444435

445436
def _set_pixel(self):
@@ -472,7 +463,6 @@ def _set_point(self):
472463
def _set_triangle(self, rot, skip):
473464
self._transform = Affine2D().scale(0.5).rotate_deg(rot)
474465
self._snap_threshold = 5.0
475-
fs = self.get_fillstyle()
476466

477467
if not self._half_fill():
478468
self._path = self._triangle_path
@@ -482,6 +472,7 @@ def _set_triangle(self, rot, skip):
482472
self._triangle_path_d,
483473
self._triangle_path_r]
484474

475+
fs = self.get_fillstyle()
485476
if fs == 'top':
486477
self._path = mpaths[(0 + skip) % 4]
487478
self._alt_path = mpaths[(2 + skip) % 4]
@@ -514,26 +505,16 @@ def _set_triangle_right(self):
514505
def _set_square(self):
515506
self._transform = Affine2D().translate(-0.5, -0.5)
516507
self._snap_threshold = 2.0
517-
fs = self.get_fillstyle()
518508
if not self._half_fill():
519509
self._path = Path.unit_rectangle()
520510
else:
521-
# build a bottom filled square out of two rectangles, one
522-
# filled. Use the rotation to support left, right, bottom
523-
# or top
524-
if fs == 'bottom':
525-
rotate = 0.
526-
elif fs == 'top':
527-
rotate = 180.
528-
elif fs == 'left':
529-
rotate = 270.
530-
else:
531-
rotate = 90.
532-
511+
# Build a bottom filled square out of two rectangles, one filled.
533512
self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 0.5],
534513
[0.0, 0.5], [0.0, 0.0]])
535514
self._alt_path = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0],
536515
[0.0, 1.0], [0.0, 0.5]])
516+
fs = self.get_fillstyle()
517+
rotate = {'bottom': 0, 'right': 90, 'top': 180, 'left': 270}[fs]
537518
self._transform.rotate_deg(rotate)
538519
self._alt_transform = self._transform
539520

@@ -542,20 +523,13 @@ def _set_square(self):
542523
def _set_diamond(self):
543524
self._transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45)
544525
self._snap_threshold = 5.0
545-
fs = self.get_fillstyle()
546526
if not self._half_fill():
547527
self._path = Path.unit_rectangle()
548528
else:
549529
self._path = Path([[0, 0], [1, 0], [1, 1], [0, 0]])
550530
self._alt_path = Path([[0, 0], [0, 1], [1, 1], [0, 0]])
551-
if fs == 'bottom':
552-
rotate = 270.
553-
elif fs == 'top':
554-
rotate = 90.
555-
elif fs == 'left':
556-
rotate = 180.
557-
else:
558-
rotate = 0.
531+
fs = self.get_fillstyle()
532+
rotate = {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs]
559533
self._transform.rotate_deg(rotate)
560534
self._alt_transform = self._transform
561535
self._joinstyle = 'miter'
@@ -569,29 +543,20 @@ def _set_pentagon(self):
569543
self._snap_threshold = 5.0
570544

571545
polypath = Path.unit_regular_polygon(5)
572-
fs = self.get_fillstyle()
573546

574547
if not self._half_fill():
575548
self._path = polypath
576549
else:
577550
verts = polypath.vertices
578-
579551
y = (1 + np.sqrt(5)) / 4.
580-
top = Path([verts[0], verts[1], verts[4], verts[0]])
581-
bottom = Path([verts[1], verts[2], verts[3], verts[4], verts[1]])
552+
top = Path(verts[[0, 1, 4, 0]])
553+
bottom = Path(verts[[1, 2, 3, 4, 1]])
582554
left = Path([verts[0], verts[1], verts[2], [0, -y], verts[0]])
583555
right = Path([verts[0], verts[4], verts[3], [0, -y], verts[0]])
584-
585-
if fs == 'top':
586-
mpath, mpath_alt = top, bottom
587-
elif fs == 'bottom':
588-
mpath, mpath_alt = bottom, top
589-
elif fs == 'left':
590-
mpath, mpath_alt = left, right
591-
else:
592-
mpath, mpath_alt = right, left
593-
self._path = mpath
594-
self._alt_path = mpath_alt
556+
self._path, self._alt_path = {
557+
'top': (top, bottom), 'bottom': (bottom, top),
558+
'left': (left, right), 'right': (right, left),
559+
}[self.get_fillstyle()]
595560
self._alt_transform = self._transform
596561

597562
self._joinstyle = 'miter'
@@ -600,29 +565,20 @@ def _set_star(self):
600565
self._transform = Affine2D().scale(0.5)
601566
self._snap_threshold = 5.0
602567

603-
fs = self.get_fillstyle()
604568
polypath = Path.unit_regular_star(5, innerCircle=0.381966)
605569

606570
if not self._half_fill():
607571
self._path = polypath
608572
else:
609573
verts = polypath.vertices
610-
611574
top = Path(np.concatenate([verts[0:4], verts[7:10], verts[0:1]]))
612575
bottom = Path(np.concatenate([verts[3:8], verts[3:4]]))
613576
left = Path(np.concatenate([verts[0:6], verts[0:1]]))
614577
right = Path(np.concatenate([verts[0:1], verts[5:10], verts[0:1]]))
615-
616-
if fs == 'top':
617-
mpath, mpath_alt = top, bottom
618-
elif fs == 'bottom':
619-
mpath, mpath_alt = bottom, top
620-
elif fs == 'left':
621-
mpath, mpath_alt = left, right
622-
else:
623-
mpath, mpath_alt = right, left
624-
self._path = mpath
625-
self._alt_path = mpath_alt
578+
self._path, self._alt_path = {
579+
'top': (top, bottom), 'bottom': (bottom, top),
580+
'left': (left, right), 'right': (right, left),
581+
}[self.get_fillstyle()]
626582
self._alt_transform = self._transform
627583

628584
self._joinstyle = 'bevel'
@@ -631,32 +587,22 @@ def _set_hexagon1(self):
631587
self._transform = Affine2D().scale(0.5)
632588
self._snap_threshold = None
633589

634-
fs = self.get_fillstyle()
635590
polypath = Path.unit_regular_polygon(6)
636591

637592
if not self._half_fill():
638593
self._path = polypath
639594
else:
640595
verts = polypath.vertices
641-
642596
# not drawing inside lines
643597
x = np.abs(np.cos(5 * np.pi / 6.))
644598
top = Path(np.concatenate([[(-x, 0)], verts[[1, 0, 5]], [(x, 0)]]))
645599
bottom = Path(np.concatenate([[(-x, 0)], verts[2:5], [(x, 0)]]))
646600
left = Path(verts[0:4])
647601
right = Path(verts[[0, 5, 4, 3]])
648-
649-
if fs == 'top':
650-
mpath, mpath_alt = top, bottom
651-
elif fs == 'bottom':
652-
mpath, mpath_alt = bottom, top
653-
elif fs == 'left':
654-
mpath, mpath_alt = left, right
655-
else:
656-
mpath, mpath_alt = right, left
657-
658-
self._path = mpath
659-
self._alt_path = mpath_alt
602+
self._path, self._alt_path = {
603+
'top': (top, bottom), 'bottom': (bottom, top),
604+
'left': (left, right), 'right': (right, left),
605+
}[self.get_fillstyle()]
660606
self._alt_transform = self._transform
661607

662608
self._joinstyle = 'miter'
@@ -665,14 +611,12 @@ def _set_hexagon2(self):
665611
self._transform = Affine2D().scale(0.5).rotate_deg(30)
666612
self._snap_threshold = None
667613

668-
fs = self.get_fillstyle()
669614
polypath = Path.unit_regular_polygon(6)
670615

671616
if not self._half_fill():
672617
self._path = polypath
673618
else:
674619
verts = polypath.vertices
675-
676620
# not drawing inside lines
677621
x, y = np.sqrt(3) / 4, 3 / 4.
678622
top = Path(verts[[1, 0, 5, 4, 1]])
@@ -681,18 +625,10 @@ def _set_hexagon2(self):
681625
[(x, y)], verts[:3], [(-x, -y), (x, y)]]))
682626
right = Path(np.concatenate([
683627
[(x, y)], verts[5:2:-1], [(-x, -y)]]))
684-
685-
if fs == 'top':
686-
mpath, mpath_alt = top, bottom
687-
elif fs == 'bottom':
688-
mpath, mpath_alt = bottom, top
689-
elif fs == 'left':
690-
mpath, mpath_alt = left, right
691-
else:
692-
mpath, mpath_alt = right, left
693-
694-
self._path = mpath
695-
self._alt_path = mpath_alt
628+
self._path, self._alt_path = {
629+
'top': (top, bottom), 'bottom': (bottom, top),
630+
'left': (left, right), 'right': (right, left),
631+
}[self.get_fillstyle()]
696632
self._alt_transform = self._transform
697633

698634
self._joinstyle = 'miter'
@@ -701,28 +637,19 @@ def _set_octagon(self):
701637
self._transform = Affine2D().scale(0.5)
702638
self._snap_threshold = 5.0
703639

704-
fs = self.get_fillstyle()
705640
polypath = Path.unit_regular_polygon(8)
706641

707642
if not self._half_fill():
708643
self._transform.rotate_deg(22.5)
709644
self._path = polypath
710645
else:
711646
x = np.sqrt(2.) / 4.
712-
half = Path([[0, -1], [0, 1], [-x, 1], [-1, x],
713-
[-1, -x], [-x, -1], [0, -1]])
714-
715-
if fs == 'bottom':
716-
rotate = 90.
717-
elif fs == 'top':
718-
rotate = 270.
719-
elif fs == 'right':
720-
rotate = 180.
721-
else:
722-
rotate = 0.
723-
724-
self._transform.rotate_deg(rotate)
725-
self._path = self._alt_path = half
647+
self._path = self._alt_path = Path(
648+
[[0, -1], [0, 1], [-x, 1], [-1, x],
649+
[-1, -x], [-x, -1], [0, -1]])
650+
fs = self.get_fillstyle()
651+
self._transform.rotate_deg(
652+
{'left': 0, 'bottom': 90, 'right': 180, 'top': 270}[fs])
726653
self._alt_transform = self._transform.frozen().rotate_deg(180.0)
727654

728655
self._joinstyle = 'miter'
@@ -854,65 +781,48 @@ def _set_x(self):
854781
self._path = self._x_path
855782

856783
_plus_filled_path = Path(
857-
[(1/3, 0), (2/3, 0), (2/3, 1/3), (1, 1/3), (1, 2/3), (2/3, 2/3),
858-
(2/3, 1), (1/3, 1), (1/3, 2/3), (0, 2/3), (0, 1/3), (1/3, 1/3),
859-
(1/3, 0)], closed=True)
784+
np.array([(-1, -3), (+1, -3), (+1, -1), (+3, -1), (+3, +1), (+1, +1),
785+
(+1, +3), (-1, +3), (-1, +1), (-3, +1), (-3, -1), (-1, -1),
786+
(-1, -3)]) / 6, closed=True)
860787
_plus_filled_path_t = Path(
861-
[(1, 1/2), (1, 2/3), (2/3, 2/3), (2/3, 1), (1/3, 1), (1/3, 2/3),
862-
(0, 2/3), (0, 1/2), (1, 1/2)], closed=True)
788+
np.array([(+3, 0), (+3, +1), (+1, +1), (+1, +3),
789+
(-1, +3), (-1, +1), (-3, +1), (-3, 0),
790+
(+3, 0)]) / 6, closed=True)
863791

864792
def _set_plus_filled(self):
865-
self._transform = Affine2D().translate(-0.5, -0.5)
793+
self._transform = Affine2D()
866794
self._snap_threshold = 5.0
867795
self._joinstyle = 'miter'
868-
fs = self.get_fillstyle()
869796
if not self._half_fill():
870797
self._path = self._plus_filled_path
871798
else:
872799
# Rotate top half path to support all partitions
873-
if fs == 'top':
874-
rotate, rotate_alt = 0, 180
875-
elif fs == 'bottom':
876-
rotate, rotate_alt = 180, 0
877-
elif fs == 'left':
878-
rotate, rotate_alt = 90, 270
879-
else:
880-
rotate, rotate_alt = 270, 90
881-
882-
self._path = self._plus_filled_path_t
883-
self._alt_path = self._plus_filled_path_t
884-
self._alt_transform = Affine2D().translate(-0.5, -0.5)
885-
self._transform.rotate_deg(rotate)
886-
self._alt_transform.rotate_deg(rotate_alt)
800+
self._path = self._alt_path = self._plus_filled_path_t
801+
fs = self.get_fillstyle()
802+
self._transform.rotate_deg(
803+
{'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs])
804+
self._alt_transform = self._transform.frozen().rotate_deg(180)
887805

888806
_x_filled_path = Path(
889-
[(0.25, 0), (0.5, 0.25), (0.75, 0), (1, 0.25), (0.75, 0.5), (1, 0.75),
890-
(0.75, 1), (0.5, 0.75), (0.25, 1), (0, 0.75), (0.25, 0.5), (0, 0.25),
891-
(0.25, 0)], closed=True)
807+
np.array([(-1, -2), (0, -1), (+1, -2), (+2, -1), (+1, 0), (+2, +1),
808+
(+1, +2), (0, +1), (-1, +2), (-2, +1), (-1, 0), (-2, -1),
809+
(-1, -2)]) / 4,
810+
closed=True)
892811
_x_filled_path_t = Path(
893-
[(0.75, 0.5), (1, 0.75), (0.75, 1), (0.5, 0.75), (0.25, 1), (0, 0.75),
894-
(0.25, 0.5), (0.75, 0.5)], closed=True)
812+
np.array([(+1, 0), (+2, +1), (+1, +2), (0, +1),
813+
(-1, +2), (-2, +1), (-1, 0), (+1, 0)]) / 4,
814+
closed=True)
895815

896816
def _set_x_filled(self):
897-
self._transform = Affine2D().translate(-0.5, -0.5)
817+
self._transform = Affine2D()
898818
self._snap_threshold = 5.0
899819
self._joinstyle = 'miter'
900-
fs = self.get_fillstyle()
901820
if not self._half_fill():
902821
self._path = self._x_filled_path
903822
else:
904823
# Rotate top half path to support all partitions
905-
if fs == 'top':
906-
rotate, rotate_alt = 0, 180
907-
elif fs == 'bottom':
908-
rotate, rotate_alt = 180, 0
909-
elif fs == 'left':
910-
rotate, rotate_alt = 90, 270
911-
else:
912-
rotate, rotate_alt = 270, 90
913-
914-
self._path = self._x_filled_path_t
915-
self._alt_path = self._x_filled_path_t
916-
self._alt_transform = Affine2D().translate(-0.5, -0.5)
917-
self._transform.rotate_deg(rotate)
918-
self._alt_transform.rotate_deg(rotate_alt)
824+
self._path = self._alt_path = self._x_filled_path_t
825+
fs = self.get_fillstyle()
826+
self._transform.rotate_deg(
827+
{'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs])
828+
self._alt_transform = self._transform.frozen().rotate_deg(180)

0 commit comments

Comments
 (0)