Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scipy/spatial/_plotutils.py: 16%

77 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-12 06:31 +0000

1import numpy as np 

2from scipy._lib.decorator import decorator as _decorator 

3 

4__all__ = ['delaunay_plot_2d', 'convex_hull_plot_2d', 'voronoi_plot_2d'] 

5 

6 

7@_decorator 

8def _held_figure(func, obj, ax=None, **kw): 

9 import matplotlib.pyplot as plt 

10 

11 if ax is None: 

12 fig = plt.figure() 

13 ax = fig.gca() 

14 return func(obj, ax=ax, **kw) 

15 

16 # As of matplotlib 2.0, the "hold" mechanism is deprecated. 

17 # When matplotlib 1.x is no longer supported, this check can be removed. 

18 was_held = getattr(ax, 'ishold', lambda: True)() 

19 if was_held: 

20 return func(obj, ax=ax, **kw) 

21 try: 

22 ax.hold(True) 

23 return func(obj, ax=ax, **kw) 

24 finally: 

25 ax.hold(was_held) 

26 

27 

28def _adjust_bounds(ax, points): 

29 margin = 0.1 * points.ptp(axis=0) 

30 xy_min = points.min(axis=0) - margin 

31 xy_max = points.max(axis=0) + margin 

32 ax.set_xlim(xy_min[0], xy_max[0]) 

33 ax.set_ylim(xy_min[1], xy_max[1]) 

34 

35 

36@_held_figure 

37def delaunay_plot_2d(tri, ax=None): 

38 """ 

39 Plot the given Delaunay triangulation in 2-D 

40 

41 Parameters 

42 ---------- 

43 tri : scipy.spatial.Delaunay instance 

44 Triangulation to plot 

45 ax : matplotlib.axes.Axes instance, optional 

46 Axes to plot on 

47 

48 Returns 

49 ------- 

50 fig : matplotlib.figure.Figure instance 

51 Figure for the plot 

52 

53 See Also 

54 -------- 

55 Delaunay 

56 matplotlib.pyplot.triplot 

57 

58 Notes 

59 ----- 

60 Requires Matplotlib. 

61 

62 Examples 

63 -------- 

64 

65 >>> import numpy as np 

66 >>> import matplotlib.pyplot as plt 

67 >>> from scipy.spatial import Delaunay, delaunay_plot_2d 

68 

69 The Delaunay triangulation of a set of random points: 

70 

71 >>> rng = np.random.default_rng() 

72 >>> points = rng.random((30, 2)) 

73 >>> tri = Delaunay(points) 

74 

75 Plot it: 

76 

77 >>> _ = delaunay_plot_2d(tri) 

78 >>> plt.show() 

79 

80 """ 

81 if tri.points.shape[1] != 2: 

82 raise ValueError("Delaunay triangulation is not 2-D") 

83 

84 x, y = tri.points.T 

85 ax.plot(x, y, 'o') 

86 ax.triplot(x, y, tri.simplices.copy()) 

87 

88 _adjust_bounds(ax, tri.points) 

89 

90 return ax.figure 

91 

92 

93@_held_figure 

94def convex_hull_plot_2d(hull, ax=None): 

95 """ 

96 Plot the given convex hull diagram in 2-D 

97 

98 Parameters 

99 ---------- 

100 hull : scipy.spatial.ConvexHull instance 

101 Convex hull to plot 

102 ax : matplotlib.axes.Axes instance, optional 

103 Axes to plot on 

104 

105 Returns 

106 ------- 

107 fig : matplotlib.figure.Figure instance 

108 Figure for the plot 

109 

110 See Also 

111 -------- 

112 ConvexHull 

113 

114 Notes 

115 ----- 

116 Requires Matplotlib. 

117 

118 

119 Examples 

120 -------- 

121 

122 >>> import numpy as np 

123 >>> import matplotlib.pyplot as plt 

124 >>> from scipy.spatial import ConvexHull, convex_hull_plot_2d 

125 

126 The convex hull of a random set of points: 

127 

128 >>> rng = np.random.default_rng() 

129 >>> points = rng.random((30, 2)) 

130 >>> hull = ConvexHull(points) 

131 

132 Plot it: 

133 

134 >>> _ = convex_hull_plot_2d(hull) 

135 >>> plt.show() 

136 

137 """ 

138 from matplotlib.collections import LineCollection 

139 

140 if hull.points.shape[1] != 2: 

141 raise ValueError("Convex hull is not 2-D") 

142 

143 ax.plot(hull.points[:, 0], hull.points[:, 1], 'o') 

144 line_segments = [hull.points[simplex] for simplex in hull.simplices] 

145 ax.add_collection(LineCollection(line_segments, 

146 colors='k', 

147 linestyle='solid')) 

148 _adjust_bounds(ax, hull.points) 

149 

150 return ax.figure 

151 

152 

153@_held_figure 

154def voronoi_plot_2d(vor, ax=None, **kw): 

155 """ 

156 Plot the given Voronoi diagram in 2-D 

157 

158 Parameters 

159 ---------- 

160 vor : scipy.spatial.Voronoi instance 

161 Diagram to plot 

162 ax : matplotlib.axes.Axes instance, optional 

163 Axes to plot on 

164 show_points : bool, optional 

165 Add the Voronoi points to the plot. 

166 show_vertices : bool, optional 

167 Add the Voronoi vertices to the plot. 

168 line_colors : string, optional 

169 Specifies the line color for polygon boundaries 

170 line_width : float, optional 

171 Specifies the line width for polygon boundaries 

172 line_alpha : float, optional 

173 Specifies the line alpha for polygon boundaries 

174 point_size : float, optional 

175 Specifies the size of points 

176 

177 Returns 

178 ------- 

179 fig : matplotlib.figure.Figure instance 

180 Figure for the plot 

181 

182 See Also 

183 -------- 

184 Voronoi 

185 

186 Notes 

187 ----- 

188 Requires Matplotlib. 

189 

190 Examples 

191 -------- 

192 >>> import numpy as np 

193 >>> import matplotlib.pyplot as plt 

194 >>> from scipy.spatial import Voronoi, voronoi_plot_2d 

195 

196 Create a set of points for the example: 

197 

198 >>> rng = np.random.default_rng() 

199 >>> points = rng.random((10,2)) 

200 

201 Generate the Voronoi diagram for the points: 

202 

203 >>> vor = Voronoi(points) 

204 

205 Use `voronoi_plot_2d` to plot the diagram: 

206 

207 >>> fig = voronoi_plot_2d(vor) 

208 

209 Use `voronoi_plot_2d` to plot the diagram again, with some settings 

210 customized: 

211 

212 >>> fig = voronoi_plot_2d(vor, show_vertices=False, line_colors='orange', 

213 ... line_width=2, line_alpha=0.6, point_size=2) 

214 >>> plt.show() 

215 

216 """ 

217 from matplotlib.collections import LineCollection 

218 

219 if vor.points.shape[1] != 2: 

220 raise ValueError("Voronoi diagram is not 2-D") 

221 

222 if kw.get('show_points', True): 

223 point_size = kw.get('point_size', None) 

224 ax.plot(vor.points[:, 0], vor.points[:, 1], '.', markersize=point_size) 

225 if kw.get('show_vertices', True): 

226 ax.plot(vor.vertices[:, 0], vor.vertices[:, 1], 'o') 

227 

228 line_colors = kw.get('line_colors', 'k') 

229 line_width = kw.get('line_width', 1.0) 

230 line_alpha = kw.get('line_alpha', 1.0) 

231 

232 center = vor.points.mean(axis=0) 

233 ptp_bound = vor.points.ptp(axis=0) 

234 

235 finite_segments = [] 

236 infinite_segments = [] 

237 for pointidx, simplex in zip(vor.ridge_points, vor.ridge_vertices): 

238 simplex = np.asarray(simplex) 

239 if np.all(simplex >= 0): 

240 finite_segments.append(vor.vertices[simplex]) 

241 else: 

242 i = simplex[simplex >= 0][0] # finite end Voronoi vertex 

243 

244 t = vor.points[pointidx[1]] - vor.points[pointidx[0]] # tangent 

245 t /= np.linalg.norm(t) 

246 n = np.array([-t[1], t[0]]) # normal 

247 

248 midpoint = vor.points[pointidx].mean(axis=0) 

249 direction = np.sign(np.dot(midpoint - center, n)) * n 

250 if (vor.furthest_site): 

251 direction = -direction 

252 far_point = vor.vertices[i] + direction * ptp_bound.max() 

253 

254 infinite_segments.append([vor.vertices[i], far_point]) 

255 

256 ax.add_collection(LineCollection(finite_segments, 

257 colors=line_colors, 

258 lw=line_width, 

259 alpha=line_alpha, 

260 linestyle='solid')) 

261 ax.add_collection(LineCollection(infinite_segments, 

262 colors=line_colors, 

263 lw=line_width, 

264 alpha=line_alpha, 

265 linestyle='dashed')) 

266 

267 _adjust_bounds(ax, vor.points) 

268 

269 return ax.figure