| 1 |  |  | # Copyright (c) 2008-2016 MetPy Developers. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | # Distributed under the terms of the BSD 3-Clause License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | # SPDX-License-Identifier: BSD-3-Clause | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | Natural Neighbor Verification | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | ============================= | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | Walks through the steps of Natural Neighbor interpolation to validate that the algorithmic | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | approach taken in MetPy is correct. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | # Find natural neighbors visual test | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | # A triangle is a natural neighbor for a point if the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | # `circumscribed circle <https://en.wikipedia.org/wiki/Circumscribed_circle>`_ of the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | # triangle contains that point. It is important that we correctly grab the correct triangles | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | # for each point before proceeding with the interpolation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | # Algorithmically: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | # 1. We place all of the grid points in a KDTree. These provide worst-case O(n) time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | #    complexity for spatial searches. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | # 2. We generate a `Delaunay Triangulation <https://docs.scipy.org/doc/scipy/ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | #    reference/tutorial/spatial.html#delaunay-triangulations>`_ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | #    using the locations of the provided observations. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | # 3. For each triangle, we calculate its circumcenter and circumradius. Using | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | #    KDTree, we then assign each grid a triangle that has a circumcenter within a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  | #    circumradius of the grid's location. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | # 4. The resulting dictionary uses the grid index as a key and a set of natural | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | #    neighbor triangles in the form of triangle codes from the Delaunay triangulation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | #    This dictionary is then iterated through to calculate interpolation values. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  | # 5. We then traverse the ordered natural neighbor edge vertices for a particular | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  | #    grid cell in groups of 3 (n - 1, n, n + 1), and perform calculations to generate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  | #    proportional polygon areas. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  | #    Circumcenter of (n - 1), n, grid_location | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  | #    Circumcenter of (n + 1), n, grid_location | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  | #    Determine what existing circumcenters (ie, Delaunay circumcenters) are associated | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  | #    with vertex n, and add those as polygon vertices. Calculate the area of this polygon. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  | # 6. Increment the current edges to be checked, i.e.: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  | #    n - 1 = n, n = n + 1, n + 1 = n + 2 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  | # 7. Repeat steps 5 & 6 until all of the edge combinations of 3 have been visited. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  | # 8. Repeat steps 4 through 7 for each grid cell. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  | import matplotlib.pyplot as plt | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  | import numpy as np | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  | from scipy.spatial import ConvexHull, Delaunay, delaunay_plot_2d, Voronoi, voronoi_plot_2d | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  | from scipy.spatial.distance import euclidean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  | from metpy.gridding import polygons, triangles | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  | from metpy.gridding.interpolation import nn_point | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  | plt.rcParams['figure.figsize'] = (15, 10) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  | # For a test case, we generate 10 random points and observations, where the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  | # observation values are just the x coordinate value times the y coordinate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  | # value divided by 1000. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  | # We then create two test points (grid 0 & grid 1) at which we want to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  | # estimate a value using natural neighbor interpolation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  | # The locations of these observations are then used to generate a Delaunay triangulation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  | np.random.seed(100) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  | pts = np.random.randint(0, 100, (10, 2)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  | xp = pts[:, 0] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  | yp = pts[:, 1] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  | zp = (pts[:, 0] * pts[:, 0]) / 1000 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  | tri = Delaunay(pts) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  | delaunay_plot_2d(tri) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  | for i, zval in enumerate(zp): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |     plt.annotate('{} F'.format(zval), xy=(pts[i, 0] + 2, pts[i, 1])) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  | sim_gridx = [30., 60.] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  | sim_gridy = [30., 60.] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  | plt.plot(sim_gridx, sim_gridy, '+', markersize=10) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  | plt.axes().set_aspect('equal', 'datalim') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  | plt.title('Triangulation of observations and test grid cell ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |           'natural neighbor interpolation values') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  | members, tri_info = triangles.find_natural_neighbors(tri, list(zip(sim_gridx, sim_gridy))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  | val = nn_point(xp, yp, zp, (sim_gridx[0], sim_gridy[0]), tri, members[0], tri_info) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  | plt.annotate('grid 0: {:.3f}'.format(val), xy=(sim_gridx[0] + 2, sim_gridy[0])) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  | val = nn_point(xp, yp, zp, (sim_gridx[1], sim_gridy[1]), tri, members[1], tri_info) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  | plt.annotate('grid 1: {:.3f}'.format(val), xy=(sim_gridx[1] + 2, sim_gridy[1])) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  | # Using the circumcenter and circumcircle radius information from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  | # :func:`metpy.gridding.triangles.find_natural_neighbors`, we can visually | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  | # examine the results to see if they are correct. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  | def draw_circle(x, y, r, m, label): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |     nx = x + r * np.cos(np.deg2rad(list(range(360)))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |     ny = y + r * np.sin(np.deg2rad(list(range(360)))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |     plt.plot(nx, ny, m, label=label) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  | members, tri_info = triangles.find_natural_neighbors(tri, list(zip(sim_gridx, sim_gridy))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  | delaunay_plot_2d(tri) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  | plt.plot(sim_gridx, sim_gridy, 'ks', markersize=10) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  | for i, info in tri_info.items(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |     x_t = info['cc'][0] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |     y_t = info['cc'][1] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |     if i in members[1] and i in members[0]: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |         draw_circle(x_t, y_t, info['r'], 'm-', str(i) + ': grid 1 & 2') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |         plt.annotate(str(i), xy=(x_t, y_t), fontsize=15) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |     elif i in members[0]: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |         draw_circle(x_t, y_t, info['r'], 'r-', str(i) + ': grid 0') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |         plt.annotate(str(i), xy=(x_t, y_t), fontsize=15) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |     elif i in members[1]: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |         draw_circle(x_t, y_t, info['r'], 'b-', str(i) + ': grid 1') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |         plt.annotate(str(i), xy=(x_t, y_t), fontsize=15) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |         draw_circle(x_t, y_t, info['r'], 'k:', str(i) + ': no match') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |         plt.annotate(str(i), xy=(x_t, y_t), fontsize=9) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  | plt.axes().set_aspect('equal', 'datalim') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  | plt.legend() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  | # What?....the circle from triangle 8 looks pretty darn close. Why isn't | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  | # grid 0 included in that circle? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  | x_t, y_t = tri_info[8]['cc'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  | r = tri_info[8]['r'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  | print('Distance between grid0 and Triangle 8 circumcenter:', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |       euclidean([x_t, y_t], [sim_gridx[0], sim_gridy[0]])) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  | print('Triangle 8 circumradius:', r) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  | # Lets do a manual check of the above interpolation value for grid 0 (southernmost grid) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  | # Grab the circumcenters and radii for natural neighbors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  | cc = np.array([tri_info[m]['cc'] for m in members[0]]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  | r = np.array([tri_info[m]['r'] for m in members[0]]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  | print('circumcenters:\n', cc) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  | print('radii\n', r) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  | # Draw the natural neighbor triangles and their circumcenters. Also plot a `Voronoi diagram | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  | # <https://docs.scipy.org/doc/scipy/reference/tutorial/spatial.html#voronoi-diagrams>`_ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  | # which serves as a complementary (but not necessary) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  | # spatial data structure that we use here simply to show areal ratios. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  | # Notice that the two natural neighbor triangle circumcenters are also vertices | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  | # in the Voronoi plot (green dots), and the observations are in the the polygons (blue dots). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  | vor = Voronoi(list(zip(xp, yp))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  | voronoi_plot_2d(vor) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  | nn_ind = np.array([0, 5, 7, 8]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  | z_0 = zp[nn_ind] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  | x_0 = xp[nn_ind] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  | y_0 = yp[nn_ind] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  | for x, y, z in zip(x_0, y_0, z_0): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |     plt.annotate('{}, {}: {:.3f} F'.format(x, y, z), xy=(x, y)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  | plt.plot(sim_gridx[0], sim_gridy[0], 'k+', markersize=10) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  | plt.annotate('{}, {}'.format(sim_gridx[0], sim_gridy[0]), xy=(sim_gridx[0] + 2, sim_gridy[0])) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  | plt.plot(cc[:, 0], cc[:, 1], 'ks', markersize=15, fillstyle='none', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |          label='natural neighbor\ncircumcenters') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  | for center in cc: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |     plt.annotate('{:.3f}, {:.3f}'.format(center[0], center[1]), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |                  xy=(center[0] + 1, center[1] + 1)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  | tris = tri.points[tri.simplices[members[0]]] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  | for triangle in tris: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |     x = [triangle[0, 0], triangle[1, 0], triangle[2, 0], triangle[0, 0]] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |     y = [triangle[0, 1], triangle[1, 1], triangle[2, 1], triangle[0, 1]] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |     plt.plot(x, y, ':', linewidth=2) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  | plt.legend() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  | plt.axes().set_aspect('equal', 'datalim') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 190 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 191 |  |  | def draw_polygon_with_info(polygon, off_x=0, off_y=0): | 
            
                                                                        
                            
            
                                    
            
            
                | 192 |  |  |     """Draw one of the natural neighbor polygons with some information.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 193 |  |  |     pts = np.array(polygon)[ConvexHull(polygon).vertices] | 
            
                                                                        
                            
            
                                    
            
            
                | 194 |  |  |     for i, pt in enumerate(pts): | 
            
                                                                        
                            
            
                                    
            
            
                | 195 |  |  |         plt.plot([pt[0], pts[(i + 1) % len(pts)][0]], | 
            
                                                                        
                            
            
                                    
            
            
                | 196 |  |  |                  [pt[1], pts[(i + 1) % len(pts)][1]], 'k-') | 
            
                                                                        
                            
            
                                    
            
            
                | 197 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 198 |  |  |     avex, avey = np.mean(pts, axis=0) | 
            
                                                                        
                            
            
                                    
            
            
                | 199 |  |  |     plt.annotate('area: {:.3f}'.format(polygons.area(pts)), xy=(avex + off_x, avey + off_y), | 
            
                                                                        
                            
            
                                    
            
            
                | 200 |  |  |                  fontsize=12) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  | cc1 = triangles.circumcenter((53, 66), (15, 60), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  | cc2 = triangles.circumcenter((34, 24), (53, 66), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  | draw_polygon_with_info([cc[0], cc1, cc2]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  | cc1 = triangles.circumcenter((53, 66), (15, 60), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  | cc2 = triangles.circumcenter((15, 60), (8, 24), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  | draw_polygon_with_info([cc[0], cc[1], cc1, cc2], off_x=-9, off_y=3) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  | cc1 = triangles.circumcenter((8, 24), (34, 24), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  | cc2 = triangles.circumcenter((15, 60), (8, 24), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  | draw_polygon_with_info([cc[1], cc1, cc2], off_x=-15) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  | cc1 = triangles.circumcenter((8, 24), (34, 24), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  | cc2 = triangles.circumcenter((34, 24), (53, 66), (30, 30)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  | draw_polygon_with_info([cc[0], cc[1], cc1, cc2]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  | # Put all of the generated polygon areas and their affiliated values in arrays. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  | # Calculate the total area of all of the generated polygons. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  | areas = np.array([60.434, 448.296, 25.916, 70.647]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  | values = np.array([0.064, 1.156, 2.809, 0.225]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  | total_area = np.sum(areas) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  | print(total_area) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  | # For each polygon area, calculate its percent of total area. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  | proportions = areas / total_area | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  | print(proportions) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  | # Multiply the percent of total area by the respective values. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  | contributions = proportions * values | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  | print(contributions) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  | # The sum of this array is the interpolation value! | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  | interpolation_value = np.sum(contributions) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  | function_output = nn_point(xp, yp, zp, (sim_gridx[0], sim_gridy[0]), tri, members[0], tri_info) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  | print(interpolation_value, function_output) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  | ########################################### | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  | # The values are slightly different due to truncating the area values in | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 246 |  |  | # the above visual example to the 3rd decimal place. | 
            
                                                        
            
                                    
            
            
                | 247 |  |  |  |