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
« 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
4__all__ = ['delaunay_plot_2d', 'convex_hull_plot_2d', 'voronoi_plot_2d']
7@_decorator
8def _held_figure(func, obj, ax=None, **kw):
9 import matplotlib.pyplot as plt
11 if ax is None:
12 fig = plt.figure()
13 ax = fig.gca()
14 return func(obj, ax=ax, **kw)
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)
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])
36@_held_figure
37def delaunay_plot_2d(tri, ax=None):
38 """
39 Plot the given Delaunay triangulation in 2-D
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
48 Returns
49 -------
50 fig : matplotlib.figure.Figure instance
51 Figure for the plot
53 See Also
54 --------
55 Delaunay
56 matplotlib.pyplot.triplot
58 Notes
59 -----
60 Requires Matplotlib.
62 Examples
63 --------
65 >>> import numpy as np
66 >>> import matplotlib.pyplot as plt
67 >>> from scipy.spatial import Delaunay, delaunay_plot_2d
69 The Delaunay triangulation of a set of random points:
71 >>> rng = np.random.default_rng()
72 >>> points = rng.random((30, 2))
73 >>> tri = Delaunay(points)
75 Plot it:
77 >>> _ = delaunay_plot_2d(tri)
78 >>> plt.show()
80 """
81 if tri.points.shape[1] != 2:
82 raise ValueError("Delaunay triangulation is not 2-D")
84 x, y = tri.points.T
85 ax.plot(x, y, 'o')
86 ax.triplot(x, y, tri.simplices.copy())
88 _adjust_bounds(ax, tri.points)
90 return ax.figure
93@_held_figure
94def convex_hull_plot_2d(hull, ax=None):
95 """
96 Plot the given convex hull diagram in 2-D
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
105 Returns
106 -------
107 fig : matplotlib.figure.Figure instance
108 Figure for the plot
110 See Also
111 --------
112 ConvexHull
114 Notes
115 -----
116 Requires Matplotlib.
119 Examples
120 --------
122 >>> import numpy as np
123 >>> import matplotlib.pyplot as plt
124 >>> from scipy.spatial import ConvexHull, convex_hull_plot_2d
126 The convex hull of a random set of points:
128 >>> rng = np.random.default_rng()
129 >>> points = rng.random((30, 2))
130 >>> hull = ConvexHull(points)
132 Plot it:
134 >>> _ = convex_hull_plot_2d(hull)
135 >>> plt.show()
137 """
138 from matplotlib.collections import LineCollection
140 if hull.points.shape[1] != 2:
141 raise ValueError("Convex hull is not 2-D")
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)
150 return ax.figure
153@_held_figure
154def voronoi_plot_2d(vor, ax=None, **kw):
155 """
156 Plot the given Voronoi diagram in 2-D
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
177 Returns
178 -------
179 fig : matplotlib.figure.Figure instance
180 Figure for the plot
182 See Also
183 --------
184 Voronoi
186 Notes
187 -----
188 Requires Matplotlib.
190 Examples
191 --------
192 >>> import numpy as np
193 >>> import matplotlib.pyplot as plt
194 >>> from scipy.spatial import Voronoi, voronoi_plot_2d
196 Create a set of points for the example:
198 >>> rng = np.random.default_rng()
199 >>> points = rng.random((10,2))
201 Generate the Voronoi diagram for the points:
203 >>> vor = Voronoi(points)
205 Use `voronoi_plot_2d` to plot the diagram:
207 >>> fig = voronoi_plot_2d(vor)
209 Use `voronoi_plot_2d` to plot the diagram again, with some settings
210 customized:
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()
216 """
217 from matplotlib.collections import LineCollection
219 if vor.points.shape[1] != 2:
220 raise ValueError("Voronoi diagram is not 2-D")
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')
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)
232 center = vor.points.mean(axis=0)
233 ptp_bound = vor.points.ptp(axis=0)
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
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
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()
254 infinite_segments.append([vor.vertices[i], far_point])
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'))
267 _adjust_bounds(ax, vor.points)
269 return ax.figure