1
1
import numpy as np
2
+ import matplotlib .pyplot as plt
2
3
from matplotlib import markers
3
4
from matplotlib .path import Path
5
+ from matplotlib .testing .decorators import check_figures_equal
4
6
5
7
import pytest
6
8
@@ -26,3 +28,108 @@ def test_marker_path():
26
28
path = Path ([[0 , 0 ], [1 , 0 ]], [Path .MOVETO , Path .LINETO ])
27
29
# Checking this doesn't fail.
28
30
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