11import numpy as np
2+ import matplotlib .pyplot as plt
23from matplotlib import markers
34from matplotlib .path import Path
5+ from matplotlib .testing .decorators import check_figures_equal
46
57import pytest
68
@@ -26,3 +28,108 @@ def test_marker_path():
2628 path = Path ([[0 , 0 ], [1 , 0 ]], [Path .MOVETO , Path .LINETO ])
2729 # Checking this doesn't fail.
2830 marker_style .set_marker (path )
31+
32+
33+ class UnsnappedMarkerStyle (markers .MarkerStyle ):
34+ """
35+ A MarkerStyle where the snap threshold is force-disabled.
36+
37+ This is used to compare to polygon/star/asterisk markers which do not have
38+ any snap threshold set.
39+ """
40+ def _recache (self ):
41+ super ()._recache ()
42+ self ._snap_threshold = None
43+
44+
45+ @check_figures_equal ()
46+ def test_poly_marker (fig_test , fig_ref ):
47+ ax_test = fig_test .add_subplot ()
48+ ax_ref = fig_ref .add_subplot ()
49+
50+ # Note, some reference sizes must be different because they have unit
51+ # *length*, while polygon markers are inscribed in a circle of unit
52+ # *radius*. This introduces a factor of np.sqrt(2), but since size is
53+ # squared, that becomes 2.
54+ size = 20 ** 2
55+
56+ # Squares
57+ ax_test .scatter ([0 ], [0 ], marker = (4 , 0 , 45 ), s = size )
58+ ax_ref .scatter ([0 ], [0 ], marker = 's' , s = size / 2 )
59+
60+ # Diamonds, with and without rotation argument
61+ ax_test .scatter ([1 ], [1 ], marker = (4 , 0 ), s = size )
62+ ax_ref .scatter ([1 ], [1 ], marker = UnsnappedMarkerStyle ('D' ), s = size / 2 )
63+ ax_test .scatter ([1 ], [1.5 ], marker = (4 , 0 , 0 ), s = size )
64+ ax_ref .scatter ([1 ], [1.5 ], marker = UnsnappedMarkerStyle ('D' ), s = size / 2 )
65+
66+ # Pentagon, with and without rotation argument
67+ ax_test .scatter ([2 ], [2 ], marker = (5 , 0 ), s = size )
68+ ax_ref .scatter ([2 ], [2 ], marker = UnsnappedMarkerStyle ('p' ), s = size )
69+ ax_test .scatter ([2 ], [2.5 ], marker = (5 , 0 , 0 ), s = size )
70+ ax_ref .scatter ([2 ], [2.5 ], marker = UnsnappedMarkerStyle ('p' ), s = size )
71+
72+ # Hexagon, with and without rotation argument
73+ ax_test .scatter ([3 ], [3 ], marker = (6 , 0 ), s = size )
74+ ax_ref .scatter ([3 ], [3 ], marker = 'h' , s = size )
75+ ax_test .scatter ([3 ], [3.5 ], marker = (6 , 0 , 0 ), s = size )
76+ ax_ref .scatter ([3 ], [3.5 ], marker = 'h' , s = size )
77+
78+ # Rotated hexagon
79+ ax_test .scatter ([4 ], [4 ], marker = (6 , 0 , 30 ), s = size )
80+ ax_ref .scatter ([4 ], [4 ], marker = 'H' , s = size )
81+
82+ # Octagons
83+ ax_test .scatter ([5 ], [5 ], marker = (8 , 0 , 22.5 ), s = size )
84+ ax_ref .scatter ([5 ], [5 ], marker = UnsnappedMarkerStyle ('8' ), s = size )
85+
86+ ax_test .set (xlim = (- 0.5 , 5.5 ), ylim = (- 0.5 , 5.5 ))
87+ ax_ref .set (xlim = (- 0.5 , 5.5 ), ylim = (- 0.5 , 5.5 ))
88+
89+
90+ def test_star_marker ():
91+ # We don't really have a strict equivalent to this marker, so we'll just do
92+ # a smoke test.
93+ size = 20 ** 2
94+
95+ fig , ax = plt .subplots ()
96+ ax .scatter ([0 ], [0 ], marker = (5 , 1 ), s = size )
97+ ax .scatter ([1 ], [1 ], marker = (5 , 1 , 0 ), s = size )
98+ ax .set (xlim = (- 0.5 , 0.5 ), ylim = (- 0.5 , 1.5 ))
99+
100+
101+ # The asterisk marker is really a star with 0-size inner circle, so the ends
102+ # are corners and get a slight bevel. The reference markers are just singular
103+ # lines without corners, so they have no bevel, and we need to add a slight
104+ # tolerance.
105+ @check_figures_equal (tol = 1.45 )
106+ def test_asterisk_marker (fig_test , fig_ref , request ):
107+ ax_test = fig_test .add_subplot ()
108+ ax_ref = fig_ref .add_subplot ()
109+
110+ # Note, some reference sizes must be different because they have unit
111+ # *length*, while asterisk markers are inscribed in a circle of unit
112+ # *radius*. This introduces a factor of np.sqrt(2), but since size is
113+ # squared, that becomes 2.
114+ size = 20 ** 2
115+
116+ def draw_ref_marker (y , style , size ):
117+ # As noted above, every line is doubled. Due to antialiasing, these
118+ # doubled lines make a slight difference in the .png results.
119+ ax_ref .scatter ([y ], [y ], marker = UnsnappedMarkerStyle (style ), s = size )
120+ if request .getfixturevalue ('ext' ) == 'png' :
121+ ax_ref .scatter ([y ], [y ], marker = UnsnappedMarkerStyle (style ),
122+ s = size )
123+
124+ # Plus
125+ ax_test .scatter ([0 ], [0 ], marker = (4 , 2 ), s = size )
126+ draw_ref_marker (0 , '+' , size )
127+ ax_test .scatter ([0.5 ], [0.5 ], marker = (4 , 2 , 0 ), s = size )
128+ draw_ref_marker (0.5 , '+' , size )
129+
130+ # Cross
131+ ax_test .scatter ([1 ], [1 ], marker = (4 , 2 , 45 ), s = size )
132+ draw_ref_marker (1 , 'x' , size / 2 )
133+
134+ ax_test .set (xlim = (- 0.5 , 1.5 ), ylim = (- 0.5 , 1.5 ))
135+ ax_ref .set (xlim = (- 0.5 , 1.5 ), ylim = (- 0.5 , 1.5 ))
0 commit comments