def draw_vor(pos, partition): # stack coordinates of nodes in coor_lis to draw the Voronoi Diagram # indices of coor_lis correspond to the node coor_lis = [] for p in range(0, len(pos.keys())): coor_lis.append(pos[str(p)]) vor = Voronoi(np.stack(coor_lis)) # build dictionary to store community info # com_node = {community: [nodes in community]} com_node = {} for p, com in partition.items(): com_node.setdefault(com, []).append(p) # merge voronoi cells for each community # record attributes of vor needed to be modified regions_remove = [] point_region_remove = [] ridge_points_remove = [] ridge_vertices_remove = [] vor_ridge_points = vor.ridge_points.tolist() vor_point_region = vor.point_region.tolist() for p_lis in com_node.values(): regions_lis, point_region_lis, ridge_points_lis, ridge_vertices_lis\ = merge_vor(vor_ridge_points, vor.ridge_vertices, vor.regions, vor_point_region, p_lis) regions_remove += regions_lis point_region_remove += point_region_lis ridge_points_remove += ridge_points_lis ridge_vertices_remove += ridge_vertices_lis # modified attributes of vor # vor.point_region for r in point_region_remove: vor_point_region.remove(r) vor.point_region = np.array(vor_point_region) # vor.regions for i in regions_remove: vor.regions.remove(i) # vor.ridge_points for pair in ridge_points_remove: vor_ridge_points.remove(pair) vor.ridge_points = np.array(vor_ridge_points) # vor.ridge_vertices for pair in ridge_vertices_remove: try: vor.ridge_vertices.remove(pair) except: v1, v2 = pair vor.ridge_vertices.remove([v2, v1]) # plot Voronoi diagram voronoi_plot_2d(vor, show_vertices=False, line_width=0) plt.show()
def calc_voronoi_tessellation( x_p, y_p, #max_area=1.5, periodic=False, SX=None, SY=None, distance_cut=None): ''' Use the scipy library on the given numpy arrays for the positions of the particles x_p: numpy array containing all x-positions of particles y_p: numpy array containing all y-positions of particles #not used, not appropriate in original tessellation #max_area: a hack method to eliminate coloring in # edges when the particles are in clumps periodic: boolean to determine whether to consider PBC SX: system size, in x, necessary for PBC SY: system size, in y, necessary for PBC ''' if periodic: if SX == None or SY == None: print("Can't make periodic Voronoi diagram without these.") return #total number of particles in the system n = len(x_p) #new numpy array to hold the #periodic repeats + original system tiled_x_p = np.zeros(n * 9) tiled_y_p = np.zeros(n * 9) #loop through the neighboring tiles for i, shiftx in enumerate([-1.0, 0.0, 1.0]): for j, shifty in enumerate([-1.0, 0.0, 1.0]): #nifty numpy array math for #creating the periodic repeats tiled_x_p[(i + j * 3) * n:(i + j * 3 + 1) * n] = x_p + shiftx * SX tiled_y_p[(i + j * 3) * n:(i + j * 3 + 1) * n] = y_p + shifty * SY ########################################################## #combine the x and y arrays into a single data structure #for the voronoi tessellation. ########################################################## np_points = np.column_stack((tiled_x_p, tiled_y_p)) ########################################################## #else = NOT doing PBC, still need to #put the x and y data into #a single np.array for voronoi analysis ######################################################### else: np_points = np.column_stack((x_p, y_p)) ######################################################### #do Voronoi analysis using scipy algorithm, #which calls qhull... I think # vor = Voronoi(np_points) ######################################################### ######################################################### #now we ruthlessly delete the tiled particles #so we don't include them in analysis ######################################################### if periodic: #want to delete the particles in the 8 additional tiles points_to_delete = np.zeros(8 * n) j = 0 #identify i values of particles NOT in the original box for i, point in zip(range(len(vor.points)), vor.points): #surely there is a more efficient way to #measure if particle NOT in box, #but I don't know what that is. if point[0] > SX or point[0] < 0.0 or point[1] < 0.0 or point[ 1] > SY: points_to_delete[j] = i j += 1 ########################################################### #check that all of the particles to be remove were counted #if this fails, it is game over ########################################################### if j != 8 * n: print("Somehow didn't find all of the extra particles") sys.exit() else: count = 0 ########################################################### #this is how I learned about these data structures #don't delete ########################################################### ''' for array in [vor.points, vor.vertices, vor.ridge_points, vor.regions, vor.point_region]: print("count=",count) print len(array) print array count+=1 ''' ########################################################### #helpful data structure learning tool #don't delete ########################################################### ''' for data_point in vor.point_region: print vor.points[data_point-1] ''' ########################################################### #delete the graft from the two arrays that count by points ########################################################### vor.points = np.delete(vor.points, points_to_delete, 0) vor.point_region = np.delete(vor.point_region, points_to_delete, 0) #everybody else is too full, #and needs to get trimmed #regions gets trimmed by point_region #not yet sure about the rest return vor