def player1(points,p1_stones_placed): x = int(raw_input("Please enter the x-coordinate for your move")) y = int(raw_input("Please enter the y-coordinate for your move")) vor = Voronoi(points,incremental=True) #needed or you can't add points move = np.array([[x,y]]) vor.add_points(move) print "You're new move looks like this:" voronoi_plot_2d(vor) plt.show() p1_stones_placed += 1 return move, p1_stones_placed
class VoronoiData: def __init__(self, hydrants): self.vor = Voronoi(hydrants, incremental=True) self.poly = Polygon([(float(x.split(', ')[0]), float(x.split(', ')[1])) for x in open('coords.txt').read().split('\n')[:-1]]) def polygons(self): l={} for point_index, region_index in enumerate(self.vor.point_region): region = self.vor.regions[region_index] if region == [] or -1 in region: continue points = self.vor.vertices[region] l[tuple(self.vor.points[point_index])] = points return l def valid(self, candidate): #lat, long = candidate #return (lat <= 41.861571 and lat >= 41.772414) and (long <= -71.369694 and long >= -71.472667) return self.poly.contains(Point(*candidate)) def most_vulnerable_point(self): l = self.polygons() candidates = [] for center, points in l.items(): farthest = None farthestDistance = 0.0 for p in points: dist = (p[0] - center[0])**2 + (p[1] - center[1])**2 if dist > farthestDistance: farthestDistance = dist farthest = p candidates.append((farthestDistance, farthest)) candidates = sorted(candidates, reverse=True) for candidate in candidates: if self.valid(candidate[1]): return candidate raise Exception("vulnerable point not found") def add_hydrant(self, p): self.vor.add_points([p[1]])
This is a temporary script file. """ import matplotlib import matplotlib.pyplot as plt import numpy as np import pandas as pd from scipy.spatial import Voronoi, voronoi_plot_2d df = pd.read_csv("cota.csv") stop_lat = df['stop_lat'] stop_lon = df['stop_lon'] x_y = {'x': stop_lon, 'y': stop_lat} bus_stop_loc = pd.DataFrame(x_y) vor = Voronoi(bus_stop_loc) data = pd.read_csv("cubic.csv") end = np.ndarray(shape=(2, data.shape[0])) for i in range(data.shape[0]): track = data.iloc[[i]].values track = track[0] track = track[0] track = track.split('],[') end_0 = track[len(track) - 1][:-2] end[0][i] = float(end_0.split(',')[0]) end[1][i] = float(end_0.split(',')[1]) data = pd.read_csv("cubic.csv") start = np.ndarray(shape=(2, data.shape[0]))
def draw_vor(graph,pos, partition,num_ps,length,width,r,num_rp): # 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())): # p in this case. #todo: more general #for p in pos.keys(): coor_lis.append(pos[str(p)]) vorpoints = np.stack(coor_lis) lim = len(coor_lis) """ # add boundary points for existing points with partitions boundary_points, partition2 = add_boundary_points(pos,partition, num_ps, length, width,graph) vorpoints2 = np.concatenate((vorpoints, boundary_points)) # add random long distance points # they are not in the partition list random_points = gencoordinates(-10, 10, vorpoints2,r,num_rp) """ #vorpoints3 = np.concatenate((vorpoints, boundary_points, random_points)) #vor = Voronoi(vorpoints3) #vor = Voronoi(vorpoints2) vor = Voronoi(vorpoints) """ print(vor._ridge_dict) print(vor.ndim) print(vor.npoints) print(vor._points) print(vor.min_bound) print(vor.max_bound) return 0 """ voronoi_plot_2d(vor, show_vertices=False) plt.show() # 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 ax = plt.subplot(1, 1, 1) indicator = 1 #print(len(com_node.keys())) for nodes in com_node.values(): #print(indicator) indicator += 1 points, shape = merge_vor(vor, nodes, lim) #shape = merge_vor(vor, nodes, lim) for coords in points: ax.scatter(coords[0], coords[1], c='steelblue') try: for polygon in shape: x, y = polygon.exterior.xy ax.plot(x, y) except: x, y = shape.exterior.xy ax.plot(x, y) plt.show() """
#!/usr/bin/env python3 import pyautogui, sys import numpy as np import time from scipy.spatial import Voronoi, voronoi_plot_2d import matplotlib.pyplot as plt print('Press Ctrl-C to quit.') data = [] i = 0 try: while True: time.sleep(3) data.append(pyautogui.position()) positionStr = 'X: ' + str(data[i][0]).rjust(4) + ' Y: ' + str( data[i][1]).rjust(4) + '\n' print(positionStr) #print(positionStr, end='') #print('\b' * len(positionStr), end='', flush=True) i += 1 except KeyboardInterrupt: print('\n') data = np.array(data) vor = Voronoi(data) voronoi_plot_2d(vor) plt.savefig('vor.png', format='png', dpi=300) plt.show()
def __init__(self, seed=None): # generate solution with seed list if seed is not None: self.positions = np.array(seed) # generate random solution else: # auxiliary random function which never returns 0 def rand_nonzero(): temp = np.random.rand() while temp == 0.0: temp = np.random.rand() return temp # random generate self.positions = np.array([[ rand_nonzero() * CONFIG['keyboard_width'], rand_nonzero() * CONFIG['keyboard_height'] ] for i in range(Solution.num_alphabet)]) # calculate necessary values # calculate area of polygon using showlace formula def poly_area(x, y): return 0.5 * np.abs( np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))) # expand voronoi diagram for 4-directions under = self.positions * np.array([1, -1]) right = self.positions * np.array([-1, 1]) + np.array( [2 * CONFIG['keyboard_width'], 0]) upper = self.positions * np.array([1, -1]) + np.array( [0, 2 * CONFIG['keyboard_height']]) left = self.positions * np.array([-1, 1]) points = np.concatenate((self.positions, under, right, upper, left), axis=0) # make voronoi diagram vor = Voronoi(points) # list of areas of each voronoi cells areas = [] # list of rectangular areas of each voronoi cells areas_rect = [] # list of central points of each voronoi cells central_points = [] # list of number of fingers correponding to alphabets which_finger = [] # list of coordinates of vertices of each voronoi regions voronoi_edges = [] # for each cells from a to spacebar, calculate area of cells for i in range(Solution.num_alphabet): index_region = vor.point_region[i] index_vertices = vor.regions[index_region] # coordinate of each vertices x_coord = [] y_coord = [] # calculate areas for j in index_vertices: x_coord.append(vor.vertices[j][0]) y_coord.append(vor.vertices[j][1]) areas.append(poly_area(x_coord, y_coord)) # calculate vertices of voronoi region edge_vertices = [] for j in index_vertices: edge_vertices.append(vor.vertices[j]) voronoi_edges.append(edge_vertices) # calculate min and max of x, y coord min_x = min(x_coord) max_x = max(x_coord) min_y = min(y_coord) max_y = max(y_coord) # calculate rectangular areas rect_width = abs(max_x - min_x) rect_height = abs(max_y - min_y) areas_rect.append(rect_width * rect_height) # calculate central point of each voronoi cells cent_x = (min_x + max_x) / 2 cent_y = (min_y + max_y) / 2 central_points.append([cent_x, cent_y]) # calculate which finger will push the key which_finger.append(Solution.field.which_finger([cent_x, cent_y])) # add attributes self.areas = areas self.areas_rect = areas_rect self.central_points = central_points self.which_finger = which_finger self.voronoi_edges = voronoi_edges self.vor = vor
def subplot_boundary(geneID, coord, count, classLabel, p, ax=None, fdr=False, point_size=5, class_line_width=2.5, **kw): ''' plot spatial expression as voronoi tessellation. :param file: geneID; spatial coordinates (n, 2); normalized count: shape (n); ''' points = coord count = count newLabels = classLabel # first estimate mean distance between points-- p_dist = cdist(points, points) p_dist[p_dist == 0] = np.max(p_dist, axis=0)[0] norm_dist = np.mean(np.min(p_dist, axis=0)) # find points at edge, add three layers of new points x_min = np.min(points, axis=0)[0] - 3 * norm_dist y_min = np.min(points, axis=0)[1] - 3 * norm_dist x_max = np.max(points, axis=0)[0] + 3 * norm_dist y_max = np.max(points, axis=0)[1] + 3 * norm_dist n_x = int((x_max - x_min) / norm_dist) + 1 n_y = int((y_max - y_min) / norm_dist) + 1 # create a mesh x = np.linspace(x_min, x_max, n_x) y = np.linspace(y_min, y_max, n_y) xv, yv = np.meshgrid(x, y) # now select points outside of hull, and merge hull = Delaunay(points) grid_points = np.hstack((xv.reshape(-1, 1), yv.reshape(-1, 1))) pad_points = grid_points[np.where(hull.find_simplex(grid_points) < 0)[0]] pad_dist = cdist(pad_points, points) pad_points = pad_points[np.where(np.min(pad_dist, axis=1) > norm_dist)[0]] all_points = np.vstack((points, pad_points)) ori_len = points.shape[0] vor = Voronoi(all_points) if kw.get("show_points", False): ax.plot(points[0:ori_len, 0], points[0:ori_len, 1], ".", markersize=point_size) # for loop for plotting is slow, consider to vectorize to speedup # doesn;t mater for now unless you have many point or genes boundary_segments = [] for kk, ii in vor.ridge_dict.items(): if kk[0] < ori_len and kk[1] < ori_len: if newLabels[kk[0]] != newLabels[kk[1]]: boundary_segments.append(vor.vertices[ii]) ax.add_collection( LineCollection(boundary_segments, colors="k", lw=class_line_width, alpha=1, linestyles="solid")) ax.set_xlim(x_min + 1 * norm_dist, x_max - 1 * norm_dist) ax.set_ylim(y_min + 1 * norm_dist, y_max - 1 * norm_dist) if fdr: titleText = geneID + '\n' + 'fdr: ' + str("{:.2e}".format(p)) else: titleText = geneID + '\n' + 'p_value: ' + str("{:.2e}".format(p)) titleText = kw.get("set_title", titleText) fontsize = kw.get("fontsize", 8) ax.set_title(titleText, fontname="Arial", fontsize=8)
def subplot_voronoi_boundary_12x18(geneID, coord, count, classLabel, p, ax, fdr=False, point_size=0.5, line_colors='k', class_line_width=0.8, line_width=0.05, line_alpha=1.0, **kw): ''' plot spatial expression as voronoi tessellation highlight boundary between classes :param file: geneID; coord: spatial coordinates (n, 2); count: normalized gene expression; predicted cell class calls (n); p: graph cut p-value. ''' points = coord count = count newLabels = classLabel p_dist = cdist(points, points) p_dist[p_dist == 0] = np.max(p_dist, axis=0)[0] norm_dist = np.mean(np.min(p_dist, axis=0)) # find points at edge, add three layers of new points x_min = np.min(points, axis=0)[0] - 3 * norm_dist y_min = np.min(points, axis=0)[1] - 3 * norm_dist x_max = np.max(points, axis=0)[0] + 3 * norm_dist y_max = np.max(points, axis=0)[1] + 3 * norm_dist n_x = int((x_max - x_min) / norm_dist) + 1 n_y = int((y_max - y_min) / norm_dist) + 1 # create a mesh x = np.linspace(x_min, x_max, n_x) y = np.linspace(y_min, y_max, n_y) xv, yv = np.meshgrid(x, y) # now select points outside of hull, and merge hull = Delaunay(points) grid_points = np.hstack((xv.reshape(-1, 1), yv.reshape(-1, 1))) pad_points = grid_points[np.where(hull.find_simplex(grid_points) < 0)[0]] pad_dist = cdist(pad_points, points) pad_points = pad_points[np.where(np.min(pad_dist, axis=1) > norm_dist)[0]] all_points = np.vstack((points, pad_points)) ori_len = points.shape[0] vor = Voronoi(all_points) if kw.get("show_points", True): ax.plot(points[0:ori_len, 0], points[0:ori_len, 1], ".", markersize=point_size) patches = [] # but we onl use the original points fot plotting for i in np.arange(ori_len): good_ver = vor.vertices[vor.regions[vor.point_region[i]]] polygon = Polygon(good_ver, True) patches.append(polygon) pc = PatchCollection(patches, cmap=cm.PiYG, alpha=1) pc.set_array(np.array(count)) ax.add_collection(pc) # for loop for plotting is slow, consider to vectorize to speedup # doesn;t mater for now unless you have many point or genes finite_segments = [] boundary_segments = [] for kk, ii in vor.ridge_dict.items(): if kk[0] < ori_len and kk[1] < ori_len: if newLabels[kk[0]] != newLabels[kk[1]]: boundary_segments.append(vor.vertices[ii]) else: finite_segments.append(vor.vertices[ii]) ax.add_collection( LineCollection( boundary_segments, ### boundary colors="k", lw=class_line_width, alpha=1, linestyles="solid")) ax.add_collection( LineCollection( finite_segments, ## other line in loop colors=line_colors, lw=line_width, alpha=line_alpha, linestyle="solid")) ax.set_xlim(x_min + 1 * norm_dist, x_max - 1 * norm_dist) ax.set_ylim(y_min + 1 * norm_dist, y_max - 1 * norm_dist) # also remember to add color bar #plt.colorbar(pc) if fdr: titleText = geneID + ' ' + '' + str("{0:.1e}".format(p)) else: titleText = geneID + ' ' + 'p_value: ' + str("{0:1e}".format(p)) titleText = kw.get("set_title", titleText) fontsize = kw.get("fontsize", 3.5) ax.set_title(titleText, fontname="Arial", fontsize=fontsize, y=0.85)
def __init__(self, points=None): """Creating a new instance of AlphaSpheres With an array of three dimensional positions (`points`) the resultant set of alpha-spheres is returned as a class AlphaSpheres. Parameters ---------- points: ndarray (shape=[n_points,3], dtype=float) Array with the three dimensional coordinates of the input points. Examples -------- See Also -------- Notes ----- """ self.points = None self.n_points = None self.centers = None self.points_of_alpha_sphere = None self.radii = None self.n_alpha_spheres = None if points is not None: # Checking if the argument points fulfills requirements if isinstance(points, (list, tuple)): points = np.array(points) elif isinstance(points, np.ndarray): pass else: raise ValueError( "The argument points needs to be a numpy array with shape (n_points, 3)" ) if (len(points.shape) != 2) and (points.shape[1] != 3): raise ValueError( "The argument points needs to be a numpy array with shape (n_points, 3)" ) # Saving attributes points and n_points self.points = points self.n_points = points.shape[0] # Voronoi class to build the alpha-spheres voronoi = Voronoi(self.points) # The alpha-spheres centers are the voronoi vertices self.centers = voronoi.vertices self.n_alpha_spheres = self.centers.shape[0] # Let's compute the 4 atoms' sets in contact with each alpha-sphere self.points_of_alpha_sphere = [ [] for ii in range(self.n_alpha_spheres) ] n_regions = len(voronoi.regions) region_point = { voronoi.point_region[ii]: ii for ii in range(self.n_points) } for region_index in range(n_regions): region = voronoi.regions[region_index] if len(region) > 0: point_index = region_point[region_index] for vertex_index in region: if vertex_index != -1: self.points_of_alpha_sphere[vertex_index].append( point_index) for ii in range(self.n_alpha_spheres): self.points_of_alpha_sphere[ii] = sorted( self.points_of_alpha_sphere[ii]) # Let's finally compute the radius of each alpha-sphere self.radii = [] for ii in range(self.n_alpha_spheres): radius = euclidean( self.centers[ii], self.points[self.points_of_alpha_sphere[ii][0]]) self.radii.append(radius) self.points_of_alpha_sphere = np.array(self.points_of_alpha_sphere) self.radii = np.array(self.radii)
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
def create_grid_and_edges(data, drone_altitude, safety_distance): """ Returns a grid representation of a 2D configuration space along with Voronoi graph edges given obstacle data and the drone's altitude. """ # minimum and maximum north coordinates north_min = np.floor(np.min(data[:, 0] - data[:, 3])) north_max = np.ceil(np.max(data[:, 0] + data[:, 3])) # minimum and maximum east coordinates east_min = np.floor(np.min(data[:, 1] - data[:, 4])) east_max = np.ceil(np.max(data[:, 1] + data[:, 4])) # given the minimum and maximum coordinates we can # calculate the size of the grid. north_size = int(np.ceil((north_max - north_min + 1))) east_size = int(np.ceil((east_max - east_min + 1))) # Initialize an empty grid grid = np.zeros((north_size, east_size)) # Populate the grid with obstacles for i in range(data.shape[0]): north, east, alt, d_north, d_east, d_alt = data[i, :] if alt + d_alt + safety_distance > drone_altitude: obstacle = [ int(np.clip(north - d_north - safety_distance - north_min, 0, north_size-1)), int(np.clip(north + d_north + safety_distance - north_min, 0, north_size-1)), int(np.clip(east - d_east - safety_distance - east_min, 0, east_size-1)), int(np.clip(east + d_east + safety_distance - east_min, 0, east_size-1)), ] grid[obstacle[0]:obstacle[1]+1, obstacle[2]:obstacle[3]+1] = 1 # add center of obstacles to points list points.append([north - north_min, east - east_min]) # TODO: create a voronoi graph based on # location of obstacle centres graph = Voronoi(points) # TODO: check each edge from graph.ridge_vertices for collision edges = [] for v in graph.ridge_vertices: p1 = graph.vertices[v[0]] p2 = graph.vertices[v[1]] cells = list(bresenham(int(p1[0]), int(p1[1]), int(p2[0]), int(p2[1]))) hit = False for c in cells: # First check if we're off the map if np.amin(c) < 0 or c[0] >= grid.shape[0] or c[1] >= grid.shape[1]: hit = True break # Next check if we're in collision if grid[c[0], c[1]] == 1: hit = True break # If the edge does not hit on obstacle # add it to the list if not hit: # array to tuple for future graph creation step) p1 = (p1[0], p1[1]) p2 = (p2[0], p2[1]) edges.append((p1, p2)) return grid, edges
def __init__(self, hx=0, hy=0, x=[], y=[]): # размеры self.hx, self.hy = self.h = (hx, hy) # приблизительная длина стороны квадрата # в котором в среднем есть одна точка self.num=num=math.sqrt(hx*hy/len(x)) # формирую узлы с шагом num # по осям d_x=list(np.arange(-num,hx+2*num,num)) d_y=list(np.arange(-num,hy+2*num,num)) # формируем границу, с ней будет удобнее контроллировать граничные условия granica=[d_x*2+[-num]*(len(d_y)-2)+[hx+num]*(len(d_y)-2), [-num]*len(d_x)+[hy+num]*len(d_x)+d_y[1:-1]*2] # координаты всех узлов, и граничных и внутренних. Какие из них какими # будут, выяснится после построения диаграммы Вороного self.x, self.y = [list(x)+granica[0],list(y)+granica[1]] # центр слитка self.materialcentercell = self.getcellinarea((hx/2-num,hx/2+num),(hy/2-num,hy/2+num)) # количество ячеек, клеток. self.cellsnumber = cellsnumber = len(self.x) # строим диаграмму Вороного self.voron = Voronoi(np.array([self.x,self.y]).transpose()) # в этом массиве будет инофрмация о соседях для каждой клетки self.neighbours=[] # здесь будут хранится для каждой клетки расстояния до соседей self.distances_to_neighbours=[] # пока все клетки внутренние # для каждой точки 0-внутренняя, 1-граничная self.borders=[0]*cellsnumber # здесь будут храниться для каждой клетки площади поверхностей соприкосновения с соседними self.contact_surface_area=[] # для вычисления условия сходимости self.sumcontactareadevideddistance=[math.inf]*cellsnumber # полная площадь соприкосновения каждой ячейки с другим ячейками self.complete_cell_surface_area=[math.inf]*cellsnumber # площадь поверхности клетки # объем ячейки, по умолчанию -1=infinite self.volume=[-1]*cellsnumber # инициализируем массивы для списков соседей, растояний до них, и площади соприкосновения for i in range(cellsnumber): self.neighbours.append([]) self.distances_to_neighbours.append([]) self.contact_surface_area.append([]) # находим для каждой точкие его соседей for i in self.voron.ridge_points: self.neighbours[i[0]].append(i[1]) self.neighbours[i[1]].append(i[0]) # находим для каждой точки расстояния до его соседей и площади поверхностей # соприкосновения с ячейками соседей. Соседей перечисляем # согласно последовательности списка в neighbours for i in range(len(self.neighbours)): # Ищем объем ячейки, если она конечная, если бесконечная, то граница xx=[] yy=[] flag=0 # по умолчанию точка внутренняя for vert in self.voron.regions[self.voron.point_region[i]]: xx.append(self.voron.vertices[vert][0]) yy.append(self.voron.vertices[vert][1]) if vert==-1: flag=1 # значит точка граничная self.borders[i]=1 # запомним, что граничная if flag==0: self.volume[i]=PolyArea(xx,yy) self.mass[i]=self.ro()*self.volume[i] # клетка i неграничная -> считаем позже площадь поверхности # перед этим площадь math.inf переводим в 0. self.complete_cell_surface_area[i]=0 self.sumcontactareadevideddistance[i]=0 # закончили вычислять объемы (размеры) ячеек for ii in range(len(self.neighbours[i])): # ищем расстояния self.distances_to_neighbours[i].append(\ euklid_distance(\ (self.x[i],self.y[i]),\ (self.x[self.neighbours[i][ii]],self.y[self.neighbours[i][ii]])\ )) # ищем площади поверхностей (граней) касания # слабое место, поскольку свойство ridge_dict не описано в документации # но фактически есть и как раз то, что мне здесь нужно. # ridge_dict - словарь, ключь - пары соседних в диаграмме points, # значение - пары vertices вершин - концов перпендикулярного ребра temp1=(i,self.neighbours[i][ii]) temp2=(self.neighbours[i][ii],i) tmp_vertices = [] if temp1 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp1] elif temp2 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp2] if -1 in tmp_vertices: # бесконечно ли ребро self.contact_surface_area[i].append(math.inf) else: self.contact_surface_area[i].append(\ euklid_distance(\ self.voron.vertices[tmp_vertices[0]],\ self.voron.vertices[tmp_vertices[1]]\ )) self.complete_cell_surface_area[i]+=self.contact_surface_area[i][ii] self.sumcontactareadevideddistance[i]+=(self.contact_surface_area[i][ii]/self.distances_to_neighbours[i][ii]) if self.sumcontactareadevideddistance[i]==self.mass[i]==math.inf: self.sumcontactareadevideddistance[i]=math.inf else: self.sumcontactareadevideddistance[i]/=self.mass[i] self.polygons =[] # строим полигоны, которые поместим потом на рисунок self.markphase=[] # точка в центре полигона, маркер ликвидуса/солидуса # физические парметры слитка для возможного анализа self.materialmass = sum(filter(lambda x:x<math.inf,self.mass)) # фактическая масса слитка self.maxcellmass = max(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.mincellmass = min(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.materialvolume = sum(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mincellvolume = min(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.maxcellvolume = max(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mindistance=min(list(map(min,self.distances_to_neighbours))) self.maxdistance=max(list(map(max,self.distances_to_neighbours))) self.maxcellsurfacearea=max(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) self.mincellsurfacearea=min(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) suftemp=max(filter(lambda x:x<math.inf,self.sumcontactareadevideddistance)) self.sufficientstabilitycondition_dt=(self.c()/self.k(0))/suftemp # 0.97 чтобы чуточку меньше взять, чем позволено рассуждениями self.dt = 0.99 * self.sufficientstabilitycondition_dt # in seconds self.life = 0 self.CellProtocolTime=[] # здесь запоманаем возраст и температуру self.CellProtocolT =[] # какой-нибудь клетки self.voron.close() # больше точек не добавляем self.ax = [] self.pathx=[] # для рисунка полигонов self.pathy=[] # для рисунка полигонов for i in range(len(self.voron.point_region)): self.pathx.append([]) self.pathy.append([]) if self.voron.regions[self.voron.point_region[i]].count(-1)==0\ and len(self.voron.regions[self.voron.point_region[i]])>0: for ii in self.voron.regions[self.voron.point_region[i]]: self.pathx[i].append(self.voron.vertices[ii][0]) self.pathy[i].append(self.voron.vertices[ii][1]) self.flag_fig=0 # fignumber=fignumber+1 # self.fig=plt.figure(fignumber, figsize=(10,10)) self.flag_printtcircle=0 # self.flag_nexttime=0 self.flag_plotpolygon=0 self.ax_printtcircle=0 self.ax_nexttime=0
class Ingot: def __init__(self, hx=0, hy=0, x=[], y=[]): # размеры self.hx, self.hy = self.h = (hx, hy) # приблизительная длина стороны квадрата # в котором в среднем есть одна точка self.num=num=math.sqrt(hx*hy/len(x)) # формирую узлы с шагом num # по осям d_x=list(np.arange(-num,hx+2*num,num)) d_y=list(np.arange(-num,hy+2*num,num)) # формируем границу, с ней будет удобнее контроллировать граничные условия granica=[d_x*2+[-num]*(len(d_y)-2)+[hx+num]*(len(d_y)-2), [-num]*len(d_x)+[hy+num]*len(d_x)+d_y[1:-1]*2] # координаты всех узлов, и граничных и внутренних. Какие из них какими # будут, выяснится после построения диаграммы Вороного self.x, self.y = [list(x)+granica[0],list(y)+granica[1]] # центр слитка self.materialcentercell = self.getcellinarea((hx/2-num,hx/2+num),(hy/2-num,hy/2+num)) # количество ячеек, клеток. self.cellsnumber = cellsnumber = len(self.x) # строим диаграмму Вороного self.voron = Voronoi(np.array([self.x,self.y]).transpose()) # в этом массиве будет инофрмация о соседях для каждой клетки self.neighbours=[] # здесь будут хранится для каждой клетки расстояния до соседей self.distances_to_neighbours=[] # пока все клетки внутренние # для каждой точки 0-внутренняя, 1-граничная self.borders=[0]*cellsnumber # здесь будут храниться для каждой клетки площади поверхностей соприкосновения с соседними self.contact_surface_area=[] # для вычисления условия сходимости self.sumcontactareadevideddistance=[math.inf]*cellsnumber # полная площадь соприкосновения каждой ячейки с другим ячейками self.complete_cell_surface_area=[math.inf]*cellsnumber # площадь поверхности клетки # объем ячейки, по умолчанию -1=infinite self.volume=[-1]*cellsnumber # инициализируем массивы для списков соседей, растояний до них, и площади соприкосновения for i in range(cellsnumber): self.neighbours.append([]) self.distances_to_neighbours.append([]) self.contact_surface_area.append([]) # находим для каждой точкие его соседей for i in self.voron.ridge_points: self.neighbours[i[0]].append(i[1]) self.neighbours[i[1]].append(i[0]) # находим для каждой точки расстояния до его соседей и площади поверхностей # соприкосновения с ячейками соседей. Соседей перечисляем # согласно последовательности списка в neighbours for i in range(len(self.neighbours)): # Ищем объем ячейки, если она конечная, если бесконечная, то граница xx=[] yy=[] flag=0 # по умолчанию точка внутренняя for vert in self.voron.regions[self.voron.point_region[i]]: xx.append(self.voron.vertices[vert][0]) yy.append(self.voron.vertices[vert][1]) if vert==-1: flag=1 # значит точка граничная self.borders[i]=1 # запомним, что граничная if flag==0: self.volume[i]=PolyArea(xx,yy) self.mass[i]=self.ro()*self.volume[i] # клетка i неграничная -> считаем позже площадь поверхности # перед этим площадь math.inf переводим в 0. self.complete_cell_surface_area[i]=0 self.sumcontactareadevideddistance[i]=0 # закончили вычислять объемы (размеры) ячеек for ii in range(len(self.neighbours[i])): # ищем расстояния self.distances_to_neighbours[i].append(\ euklid_distance(\ (self.x[i],self.y[i]),\ (self.x[self.neighbours[i][ii]],self.y[self.neighbours[i][ii]])\ )) # ищем площади поверхностей (граней) касания # слабое место, поскольку свойство ridge_dict не описано в документации # но фактически есть и как раз то, что мне здесь нужно. # ridge_dict - словарь, ключь - пары соседних в диаграмме points, # значение - пары vertices вершин - концов перпендикулярного ребра temp1=(i,self.neighbours[i][ii]) temp2=(self.neighbours[i][ii],i) tmp_vertices = [] if temp1 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp1] elif temp2 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp2] if -1 in tmp_vertices: # бесконечно ли ребро self.contact_surface_area[i].append(math.inf) else: self.contact_surface_area[i].append(\ euklid_distance(\ self.voron.vertices[tmp_vertices[0]],\ self.voron.vertices[tmp_vertices[1]]\ )) self.complete_cell_surface_area[i]+=self.contact_surface_area[i][ii] self.sumcontactareadevideddistance[i]+=(self.contact_surface_area[i][ii]/self.distances_to_neighbours[i][ii]) if self.sumcontactareadevideddistance[i]==self.mass[i]==math.inf: self.sumcontactareadevideddistance[i]=math.inf else: self.sumcontactareadevideddistance[i]/=self.mass[i] self.polygons =[] # строим полигоны, которые поместим потом на рисунок self.markphase=[] # точка в центре полигона, маркер ликвидуса/солидуса # физические парметры слитка для возможного анализа self.materialmass = sum(filter(lambda x:x<math.inf,self.mass)) # фактическая масса слитка self.maxcellmass = max(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.mincellmass = min(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.materialvolume = sum(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mincellvolume = min(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.maxcellvolume = max(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mindistance=min(list(map(min,self.distances_to_neighbours))) self.maxdistance=max(list(map(max,self.distances_to_neighbours))) self.maxcellsurfacearea=max(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) self.mincellsurfacearea=min(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) suftemp=max(filter(lambda x:x<math.inf,self.sumcontactareadevideddistance)) self.sufficientstabilitycondition_dt=(self.c()/self.k(0))/suftemp # 0.97 чтобы чуточку меньше взять, чем позволено рассуждениями self.dt = 0.99 * self.sufficientstabilitycondition_dt # in seconds self.life = 0 self.CellProtocolTime=[] # здесь запоманаем возраст и температуру self.CellProtocolT =[] # какой-нибудь клетки self.voron.close() # больше точек не добавляем self.ax = [] self.pathx=[] # для рисунка полигонов self.pathy=[] # для рисунка полигонов for i in range(len(self.voron.point_region)): self.pathx.append([]) self.pathy.append([]) if self.voron.regions[self.voron.point_region[i]].count(-1)==0\ and len(self.voron.regions[self.voron.point_region[i]])>0: for ii in self.voron.regions[self.voron.point_region[i]]: self.pathx[i].append(self.voron.vertices[ii][0]) self.pathy[i].append(self.voron.vertices[ii][1]) self.flag_fig=0 # fignumber=fignumber+1 # self.fig=plt.figure(fignumber, figsize=(10,10)) self.flag_printtcircle=0 # self.flag_nexttime=0 self.flag_plotpolygon=0 self.ax_printtcircle=0 self.ax_nexttime=0 def initpolygons(self): for i in range(len(self.pathx)): self.markphase.append([]) self.polygons.append([]) if len(self.pathx[i])>0: self.polygons[i]=\ patches.Polygon(np.asarray([self.pathx[i],self.pathy[i]]).transpose(),\ color=self.colormap.to_rgba(self.T[i])) self.markphase[i]=plt.Line2D\ ([self.voron.points[i][0]],[self.voron.points[i][1]],marker=',',color='white') # self.polygons[i].set_alpha(self.alpha0) # self.flag_plotpolygon=1 # ставим флаг self.ax_nexttime=self.initfig() # инициализируем рисунок (axe) for i in range(len(self.polygons)): if self.polygons[i]!=[]: self.ax_nexttime.add_patch(self.polygons[i]) self.ax_nexttime.add_line(self.markphase[i]) # ppl.colorbar.ColorbarBase(self.ax_nexttime,cmap=self.cmap, norm=self.tcnorm) def initfig(self): # global fignumber if self.flag_fig==0: self.flag_fig=1 temp=plt.get_fignums() temp.append(0) fignumber=max(temp)+1 self.fig = plt.figure(fignumber, figsize=(10,10)) self.fig.clf() ax = self.fig.add_axes([0.05, 0.05, 0.7,0.9],axisbg='w',aspect='equal') ax.set_xlim(-self.num,hx+self.num) ax.set_ylim(-self.num,hy+self.num) axbar=self.fig.add_axes([0.8, 0.05, 0.1,0.9]) # axbar.set_xlim(0.8,0.1) # axbar.set_ylim(-self.num,hy+self.num) # mpl.colorbar.ColorbarBase(cax, cmap=cm, norm=norm, orientation='vertical') ppl.colorbar.ColorbarBase(axbar,cmap=self.cmap, norm=self.tcnorm) return(ax) def getcellinarea(self,o1,o2): for i in range(len(self.x)): if o1[0] < self.x[i] < o1[1] and o2[0] < self.y[i] < o2[1]: return(i) return(-1) def Tnext(self,cell): # Meltingpoint = MP if self.flag_plotpolygon==0: self.flag_plotpolygon=1 self.initpolygons() if self.borders[cell]: return(self.T[cell],self.cellphase[cell]) mass=self.mass[cell] phase=self.cellphase[cell] changephase=0 dQ=self.dt*sum( list(map( (lambda x: self.k((self.T[self.neighbours[cell][x]]+self.T[cell])/2)* self.contact_surface_area[cell][x]* (self.T[self.neighbours[cell][x]]-self.T[cell])/ self.distances_to_neighbours[cell][x]), range(len(self.neighbours[cell])) ))) TnextXX=self.T[cell]+dQ/(self.c()*mass) # если работаем без смены фаз, то выходим if self.phasechange == 0: return(TnextXX,0) # Если температура клетки ниже температуры плавления, # а её фаза сейчас ликвидус, вычислим next температуру в случае # кристаллизации if self.T[cell] < self.melting_point() and phase == 0: flag = np.random.uniform(TnextXX,TnextXX + self.mu()/self.c()) # для выбора: осуществлять ли фазовый переход if flag < self.melting_point(): changephase=1 phase = 1 # self.polygons[cell].set_alpha(self.alpha1) # self.count=self.count+1 # Если температура клетки выеше температуры плавления, # а её фаза сейчас солидус, вычислим next температуру в случае # плавления if self.T[cell] > self.melting_point() and phase == 1: flag = np.random.uniform(TnextXX - self.mu()/self.c(),TnextXX) # для выбора: осуществлять ли фазовый переход if flag > self.melting_point(): changephase=-1 phase = 0 # self.polygons[cell].set_alpha(self.alpha0) # self.count1=self.count1+1 self.cellphase[cell]=phase # возвращаем температуру и фазу return(TnextXX+changephase*self.mu()/self.c(),self.cellphase[cell]) def nexttime(self,times): self.life = self.life + self.dt for i in range(times): for cell in range(len(self.T)): self.T1[cell]=self.Tnext(cell)[0] change=self.T self.T=self.T1 self.T1=change # for cell in range(len(self.T)): # self.T[cell]=self.T1[cell] # протоколируем возраст и температуру клетки cell def writeTdown(self,cell): self.CellProtocolTime.append(self.life) self.CellProtocolT.append(self.T[cell]) # Раскрашиваем полигоны согласно температуре. Отмечаем цветом точки фазу def plotpolygon(self): if self.flag_plotpolygon==0: self.flag_plotpolygon=1 self.initpolygons() for cell in range(len(self.T)): if self.polygons[cell]!=[]: if self.cellphase[cell]==0: self.polygons[cell].set_color(self.colormap.to_rgba(self.T[cell])) self.markphase[cell].set_color('white') else: self.polygons[cell].set_color(self.colormap1.to_rgba(self.T[cell])) self.markphase[cell].set_color('black') # Указываем лишь только фазу def plotphase(self): if self.flag_plotpolygon==0: self.flag_plotpolygon=1 self.initpolygons() for cell in range(len(self.T)): if self.polygons[cell]!=[]: if self.cellphase[cell]==0: self.polygons[cell].set_color('white') else: self.polygons[cell].set_color('black') def printtcircle(self,n): if self.flag_printtcircle==0: self.flag_printtcircle=1 self.ax_printtcircle=self.initfig() temp=[] for i in range(n): for ii in range(len(self.circle)): for cell in self.neighbours[ii]: if self.circle[cell]==self.Tmax: temp.append(ii) for ii in temp: self.circle[ii]=self.Tmax # self.ax.clear() # self.ax.scatter(self.x,self.y,c=self.circle,edgecolors='None',cmap=self.cmap,marker='o',s=5) self.plotpolygon2(self.ax_printtcircle) def initT(self): for i in range(len(self.neighbours)): self.T[i]=self.Tmin for vert in self.voron.regions[self.voron.point_region[i]]: if vert==-1: self.T[i]=self.Tmax def distance_cells(self,c1,c2): return(euklid_distance((self.x[c1],self.y[c1]),(self.x[c2],self.y[c2]))) def ro(self): # [кг/м^3] плотность вещества return(7870) def c(self): # удельная теплоемкость # [Дж/(кг*К)] удельная теплоемкость return(300) def k(self,temp): # коэффициент теплопроводности # [Дж/(м*К*с)]=[Вт/(м*К)]=[кг*м^2/c^3] 50-100 if 0<=temp<=800: ktemp=((temp-0)/(800-0))*(14-60)+60 elif 800<=temp<=1520: ktemp=((temp-800)/(1520-800))*(34-14)+14 elif 1520<=temp: ktemp=35 return(ktemp) def mu(self): # теплота кристаллизации # [Дж/кг] return(220000) # сталь def melting_point(self): # [K] 1450—1520 °C для стали return(1500+273.15) def xycell(self,cell): return((self.x[cell],self.y[cell])) # находит центр масс для конечного полигона # (ячейки, клетки и т.п. синонимов) def masscenterpoints(self): xnew=[] for reg in self.voron.regions: tmp=[] if reg.count(-1)==0 and len(reg)>0: for i in reg: tmp.append(self.voron.vertices[i]) xnew.append(masscenter(tmp)) return(xnew) def plotpolygon2(self,ax): ax.clear() for i in range(len(self.pathx)): if len(self.pathx[i])>0: ax.fill(self.pathx[i], self.pathy[i], color=self.colormap.to_rgba(self.circle[i]))
def visualize(regions, vertices): # colorize for region in regions: polygon = vertices[region] plt.fill(*zip(*polygon), alpha=0.4) plt.plot(points[:, 0], points[:, 1], 'ko') plt.xlim(vor.min_bound[0] - 0.1, vor.max_bound[0] + 0.1) plt.ylim(vor.min_bound[1] - 0.1, vor.max_bound[1] + 0.1) plt.show() # make up data points np.random.seed(1234) # points = np.random.rand(15, 2) points = np.genfromtxt('points.csv', delimiter=',', skip_header=1) # compute Voronoi tesselation vor = Voronoi(points) regions, vertices = voronoi_finite_polygons_2d(vor, 0.01) geometry_collection = to_geometry_collection(regions, vertices) with open("polygons.json", "w") as text_file: text_file.write(dumps(geometry_collection)) # uncomment to visualize #visualize(regions, vertices)
def test_single_cell(): grid = hexa_grid3d(6, 4, 3) datasets = from_3d_voronoi(Voronoi(grid)) sheet = Sheet("test", datasets) eptm = utils.single_cell(sheet, 1) assert len(eptm.edge_df) == len(sheet.edge_df[sheet.edge_df["cell"] == 1])
[469.672398026138, 181.23222478736406], [780.8981573651962, 129.44365347161818], [449.43126510997246, 66.05255566296], [371.5017391156057, 107.81515298179967], [441.72302154567797, 293.6216292245968], [431.82311685168287, 677.9566098897028]]) # In[26]: plt.figure(figsize=(200, 80)) plt.scatter(xvals, yvals) # In[27]: plt.scatter(centers[:, 0], centers[:, 1], c='black', s=300) # In[28]: # plt.show() # In[29]: from scipy.spatial import Voronoi, voronoi_plot_2d print("Before Voronoi") vor = Voronoi(centers) print("Just after Voronoi") # voronoi_plot_2d(vor) # plt.show() print(vor.vertices) print(vor.regions)
def test_to_nd(): grid = hexa_grid2d(6, 4, 3, 3) datasets = from_2d_voronoi(Voronoi(grid)) sheet = Sheet("test", datasets) result = utils._to_3d(sheet.face_df["x"]) assert (sheet.face_df[['x', 'y', 'z']] * result).shape[1] == 3
def __init__(self, hx=0, hy=0, Tmin=0, Tmax=0, x=[], y=[], phasechange=1): # global fignumber self.hx, self.hy = self.h = (hx, hy) # размеры self.Tmin = Tmin # минимальная температура self.Tmax = Tmax # максимальная температура Tplus=self.mu()/self.c() # повышение температуры при кристаллизации self.phasechange = phasechange #YlOrRd_r,hot,autumn # self.cmap1 = plt.get_cmap('flag') # палитра для солидуса # self.cmap = plt.get_cmap('flag') # палитра для ликвидуса self.cmap1 = plt.cm.YlOrRd_r self.cmap = plt.cm.YlOrRd_r # отображение температурного диапазона в [0,1] self.tcnorm=plt.Normalize(vmin=min(0,Tmin-0.50*Tplus), vmax=Tmax+Tplus) # отображение [0,1] в палитру для ликвидуса и солидуса self.colormap=plt.cm.ScalarMappable(norm=self.tcnorm, cmap=self.cmap) self.colormap1=plt.cm.ScalarMappable(norm=self.tcnorm, cmap=self.cmap1) # формируем границу self.num=num=math.sqrt(hx*hy/len(x)) # приблизительная длина стороны квадрата # в котором в среднем есть одна точка d_x=list(np.arange(-num,hx+num,num)) # формирую узлы с шагом num d_y=list(np.arange(-num,hy+num,num)) # по осям granica=[d_x*2+[-num]*(len(d_y)-2)+[hx+num]*(len(d_y)-2), # формируем границу [-num]*len(d_x)+[hy+num]*len(d_x)+d_y[1:-1]*2] # cellsnumber=cellsnumber+len(granica[0]) # Доавляем точки границы к внутренним точкам #x=np.array([list(m.x)+granica[0],list(m.y)+granica[1]]) self.x, self.y = [list(x)+granica[0],list(y)+granica[1]] # координаты точек self.materialcentercell = self.getcellinarea((hx/2-num,hx/2+num),(hy/2-num,hy/2+num)) self.cellsnumber = len(self.x) cellsnumber = len(self.x) self.voron = Voronoi(np.array([self.x,self.y]).transpose()) self.T=[Tmax]*cellsnumber # температурное поле self.T1 = [0]*cellsnumber # self.TT = [self.T0,self.T1] self.neighbours=[] self.mass=[math.inf]*cellsnumber self.distances_to_neighbours=[] self.borders=[0]*cellsnumber # для каждой точки 0-внутренняя, 1-граничная self.circle=[self.Tmin]*cellsnumber self.circle[self.materialcentercell]=self.Tmax self.contact_surface_area=[] self.complete_cell_surface_area=[] self.sumcontactareadevideddistance=[math.inf]*cellsnumber # для вычисления условия сходимости self.volume=[-1]*cellsnumber # объем ячейки, по умолчанию -1=infinite self.cellphase=[0]*cellsnumber # 0 - ликвидус, 1 - солидус self.complete_cell_surface_area=[math.inf]*cellsnumber # площадь поверхности клетки for i in range(cellsnumber): self.neighbours.append([]) self.distances_to_neighbours.append([]) self.contact_surface_area.append([]) # находим для каждой точкие его соседей for i in self.voron.ridge_points: self.neighbours[i[0]].append(i[1]) self.neighbours[i[1]].append(i[0]) # находим для каждой точки расстояния до его соседей и площади поверхностей # соприкосновения с ячейками соседей. Соседей перечисляем # согласно последовательности списка в neighbours for i in range(len(self.neighbours)): # Ищем объем ячейки, если она конечная, если бесконечная, то граница xx=[] yy=[] flag=0 # по умолчанию точка внутренняя for vert in self.voron.regions[self.voron.point_region[i]]: xx.append(self.voron.vertices[vert][0]) yy.append(self.voron.vertices[vert][1]) if vert==-1: flag=1 # значит точка граничная self.borders[i]=1 # запомним, что граничная self.T[i]=self.Tmin if flag==0: self.volume[i]=PolyArea(xx,yy) self.mass[i]=self.ro()*self.volume[i] # клетка i неграничная -> считаем позже площадь поверхности # перед этим площадь math.inf переводим в 0. self.complete_cell_surface_area[i]=0 self.sumcontactareadevideddistance[i]=0 # закончили вычислять объемы (размеры) ячеек for ii in range(len(self.neighbours[i])): # ищем расстояния self.distances_to_neighbours[i].append(\ euklid_distance(\ (self.x[i],self.y[i]),\ (self.x[self.neighbours[i][ii]],self.y[self.neighbours[i][ii]])\ )) # ищем площади поверхностей (граней) касания # слабое место, поскольку свойство ridge_dict не описано в документации # но фактически есть и как раз то, что мне здесь нужно. # ridge_dict - словарь, ключь - пары соседних в диаграмме points, # значение - пары vertices вершин - концов перпендикулярного ребра temp1=(i,self.neighbours[i][ii]) temp2=(self.neighbours[i][ii],i) tmp_vertices = [] if temp1 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp1] elif temp2 in self.voron.ridge_dict: tmp_vertices=self.voron.ridge_dict[temp2] if -1 in tmp_vertices: # бесконечно ли ребро self.contact_surface_area[i].append(math.inf) else: self.contact_surface_area[i].append(\ euklid_distance(\ self.voron.vertices[tmp_vertices[0]],\ self.voron.vertices[tmp_vertices[1]]\ )) self.complete_cell_surface_area[i]+=self.contact_surface_area[i][ii] self.sumcontactareadevideddistance[i]+=(self.contact_surface_area[i][ii]/self.distances_to_neighbours[i][ii]) if self.sumcontactareadevideddistance[i]==self.mass[i]==math.inf: self.sumcontactareadevideddistance[i]=math.inf else: self.sumcontactareadevideddistance[i]/=self.mass[i] self.polygons =[] # строим полигоны, которые поместим потом на рисунок self.markphase=[] # точка в центре полигона, маркер ликвидуса/солидуса self.materialmass = sum(filter(lambda x:x<math.inf,self.mass)) # фактическая масса слитка self.maxcellmass = max(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.mincellmass = min(filter(lambda x:x<math.inf,self.mass)) # фактическая ... слитка self.materialvolume = sum(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mincellvolume = min(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.maxcellvolume = max(filter(lambda x:x>0,self.volume)) # фактическая ... слитка self.mindistance=min(list(map(min,self.distances_to_neighbours))) self.maxdistance=max(list(map(max,self.distances_to_neighbours))) self.maxcellsurfacearea=max(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) self.mincellsurfacearea=min(filter(lambda x:x<math.inf,self.complete_cell_surface_area)) suftemp=max(filter(lambda x:x<math.inf,self.sumcontactareadevideddistance)) self.sufficientstabilitycondition_dt=(self.c()/self.k(0))/suftemp # 0.97 чтобы чуточку меньше взять, чем позволено рассуждениями self.dt = 0.99 * self.sufficientstabilitycondition_dt # in seconds self.life = 0 self.CellProtocolTime=[] # здесь запоманаем возраст и температуру self.CellProtocolT =[] # какой-нибудь клетки self.voron.close() # больше точек не добавляем self.ax = [] self.pathx=[] # для рисунка полигонов self.pathy=[] # для рисунка полигонов for i in range(len(self.voron.point_region)): self.pathx.append([]) self.pathy.append([]) if self.voron.regions[self.voron.point_region[i]].count(-1)==0\ and len(self.voron.regions[self.voron.point_region[i]])>0: for ii in self.voron.regions[self.voron.point_region[i]]: self.pathx[i].append(self.voron.vertices[ii][0]) self.pathy[i].append(self.voron.vertices[ii][1]) self.flag_fig=0 # fignumber=fignumber+1 # self.fig=plt.figure(fignumber, figsize=(10,10)) self.flag_printtcircle=0 # self.flag_nexttime=0 self.flag_plotpolygon=0 self.ax_printtcircle=0 self.ax_nexttime=0 self.count=0 # для тестирования, не нужно self.count1=0 # для тестирования, не нужно # self.alpha0 = 1 # прозрачность ликвидус, уже не нужно # self.alpha1 = 1 # прозрачнось солидус # непрозрачный, уже не нужно # self.ims=[] # FFMpegWriter = animation.writers['ffmpeg'] metadata = dict(title='Movie Test', artist='Matplotlib',comment='Movie support!') # self.writer = animation.FFMpegWriter(fps=1, metadata=metadata, extra_args=['-vcodec', 'libx264']) self.writer = animation.FFMpegWriter(fps=1, metadata=metadata, bitrate=1800)
def voronoi_from_points_numpy(points): """Generate a voronoi diagram from a set of points. Parameters ---------- points : list of list of float XYZ coordinates of the voronoi sites. Returns ------- Examples -------- .. code-block:: python from compas.datastructures import Mesh from compas.plotters import MeshPlotter from compas.geometry import closest_point_on_line_xy from compas.topology.triangulation import voronoi_from_points_numpy mesh = Mesh() mesh.add_vertex(x=0, y=0) mesh.add_vertex(x=1.5, y=0) mesh.add_vertex(x=1, y=1) mesh.add_vertex(x=0, y=2) mesh.add_face([0, 1, 2, 3]) sites = mesh.get_vertices_attributes('xy') voronoi = voronoi_from_points_numpy(sites) points = [] for xy in voronoi.vertices: points.append({ 'pos' : xy, 'radius' : 0.02, 'facecolor' : '#ff0000', 'edgecolor' : '#ffffff', }) lines = [] arrows = [] for (a, b), (c, d) in zip(voronoi.ridge_vertices, voronoi.ridge_points): if a > -1 and b > -1: lines.append({ 'start' : voronoi.vertices[a], 'end' : voronoi.vertices[b], 'width' : 1.0, 'color' : '#ff0000', }) elif a == -1: sp = voronoi.vertices[b] ep = closest_point_on_line_xy(sp, (voronoi.points[c], voronoi.points[d])) arrows.append({ 'start' : sp, 'end' : ep, 'width' : 1.0, 'color' : '#00ff00', 'arrow' : 'end' }) else: sp = voronoi.vertices[a] ep = closest_point_on_line_xy(sp, (voronoi.points[c], voronoi.points[d])) arrows.append({ 'start' : sp, 'end' : ep, 'width' : 1.0, 'color' : '#00ff00', 'arrow' : 'end' }) plotter = MeshPlotter(mesh, figsize=(10, 7)) plotter.draw_points(points) plotter.draw_lines(lines) plotter.draw_arrows(arrows) plotter.draw_vertices(radius=0.02) plotter.draw_faces() plotter.show() """ from numpy import asarray from scipy.spatial import Voronoi points = asarray(points) voronoi = Voronoi(points) return voronoi
def multipage_pdf_visualize_spatial_genes(df, locs, data_norm, cellGraph, fileName, point_size=0., **kw): ''' save spatial expression as voronoi tessellation to pdf highlight boundary between classes format: 12 by 18. :param file: df: graph cuts results; locs: spatial coordinates (n, 2); data_norm: normalized gene expression; pdf filename; point_size=0.5. ''' points = locs vor = Voronoi(points) nb_plots = int(df.shape[0]) numCols = 12 numRows = 18 nb_plots_per_page = numCols * numRows t_numRows = int(df.shape[0] / numCols) + 1 with PdfPages(fileName) as pdf: for i in np.arange(df.shape[0]): if i % nb_plots_per_page == 0: fig, axs = plt.subplots( numRows, numCols, # 8 11 figsize=(8, 11)) fig.subplots_adjust(hspace=0.3, wspace=0.3, top=0.925, right=0.925, bottom=0.075, left=0.075) geneID = df.index[i] exp = data_norm.loc[:, geneID].values if np.isnan(df.loc[geneID, ].fdr): best_Labels = np.zeros(data_norm.shape[0]) else: best_Labels = df.loc[geneID, ][4:].values.astype(int) m = int(i / numCols) % numRows n = i % numCols ax = axs[m, n] subplot_voronoi_boundary_12x18(geneID, locs, exp, best_Labels, df.loc[geneID, ].fdr, ax=ax, fdr=True, point_size=point_size, **kw) if (i + 1) % nb_plots_per_page == 0 or (i + 1) == nb_plots: for ii in np.arange(numRows): for jj in np.arange(numCols): axs[ii, jj].axis('off') pdf.savefig(fig) fig.clear() plt.close()
# Make the relevant imports including Voronoi methods import numpy as np from scipy.spatial import Voronoi, voronoi_plot_2d import matplotlib.pyplot as plt import math get_ipython().run_line_magic('matplotlib', 'inline') # In[26]: plt.rcParams["figure.figsize"] = [12, 12] # In[27]: # Recreate the figure above for a new set of random points points = np.random.randint(50, size=(50, 2)) graph = Voronoi(points) voronoi_plot_2d(graph) plt.show() # In[51]: # Read in the obstacle data filename = 'colliders.csv' data = np.loadtxt(filename, delimiter=',', dtype='Float64', skiprows=2) print(data) # In[70]: # If you want to use the prebuilt bresenham method # Import the Bresenham package
def test_issue_8051(self): points = np.array([[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2],[2, 0], [2, 1], [2, 2]]) Voronoi(points)
def create_grid_and_edges(data, drone_altitude, safety_distance): """ Returns a grid representation of a 2D configuration space along with Voronoi graph edges given obstacle data and the drone's altitude. """ # minimum and maximum north coordinates north_min = np.floor(np.min(data[:, 0] - data[:, 3])) north_max = np.ceil(np.max(data[:, 0] + data[:, 3])) # minimum and maximum east coordinates east_min = np.floor(np.min(data[:, 1] - data[:, 4])) east_max = np.ceil(np.max(data[:, 1] + data[:, 4])) # given the minimum and maximum coordinates we can # calculate the size of the grid. north_size = int(np.ceil((north_max - north_min))) east_size = int(np.ceil((east_max - east_min))) # Initialize an empty grid grid = np.zeros((north_size, east_size)) # Center offset for grid north_min_center = np.min(data[:, 0]) east_min_center = np.min(data[:, 1]) # Define a list to hold Voronoi points points = [] # Populate the grid with obstacles for i in range(data.shape[0]): north, east, alt, d_north, d_east, d_alt = data[i, :] if alt + d_alt + safety_distance > drone_altitude: obstacle = [ int(north - d_north - safety_distance - north_min_center), int(north + d_north + safety_distance - north_min_center), int(east - d_east - safety_distance - east_min_center), int(east + d_east + safety_distance - east_min_center), ] grid[obstacle[0]:obstacle[1] + 1, obstacle[2]:obstacle[3] + 1] = 1 # add center of obstacles to points list points.append([north - north_min, east - east_min]) # TODO: create a voronoi graph based on # location of obstacle centres graph = Voronoi(points) voronoi_plot_2d(graph) plt.show() #print(points) # TODO: check each edge from graph.ridge_vertices for collision edges = [] for v in graph.ridge_vertices: p1 = graph.vertices[v[0]] p2 = graph.vertices[v[1]] p1_gr = [int(round(x)) for x in p1] p2_gr = [int(round(x)) for x in p2] p = [p1_gr, p2_gr] #print(p1, p1_grid, p2, p2_grid) in_collision = True if np.amin(p) > 0 and np.amax(p[:][0]) < grid.shape[0] and np.amax( p[:][1]) < grid.shape[1]: track = bres(p1_gr, p2_gr) for q in track: #print(q) q = [int(x) for x in q] if grid[q[0], q[1]] == 1: in_collision = True break else: in_collision = False if not in_collision: edges.append((p1, p2)) return grid, edges
def create_pattern(num_cells): """ create cylinderical voronoi and line segments """ xmin, ymin, xmax, ymax = 0.0, 0.0, 1.0, 1.0 width = xmax - xmin points = np.random.uniform([xmin,ymin],[xmax,ymax],size=[num_cells,2]) points_mirrored = np.concatenate([points,points + [-width, 0.0],points + [width, 0.0],],axis=0) vor = Voronoi(points_mirrored) # 모든 ridge_vertices 에 대해서 liang_barsky_clipper 적용 ==> clipped_linesegs lineseg_dict = dict() c_point_linesegs = [[] for _ in range(num_cells)] for i, xy in enumerate(vor.points): # canonical point index if i >= 2 * num_cells: c_i = i - 2 * num_cells elif i >= num_cells: c_i = i - num_cells else: c_i =i vs = list(vor.regions[vor.point_region[i]]) evs = vs + [vs[0]] for j in range(len(vs)): v1, v2 = evs[j:j+2] if v1 >= 0 and v2 >= 0: if v1 == v2: print('*** v1 == v2',i,j,v1,v2,vor.regions[vor.point_region[i]]) # normalized v1, v2 for dict index rev = False if v1 > v2: v1, v2, rev = v2, v1, True # check if counter-clockwise x0, y0 = xy x1, y1 = vor.vertices[v1] x2, y2 = vor.vertices[v2] ccw = is_ccw(x0, y0, x1, y1, x2, y2) if rev: ccw = not ccw if (v1, v2) not in lineseg_dict: nx1, ny1, nx2, ny2, valid = liang_barsky_clipper(xmin, ymin, xmax, ymax, x1, y1, x2, y2) if valid: x1_wrapped = (x1 < 0.0 or x1 > 1.0) x2_wrapped = (x2 < 0.0 or x2 > 1.0) y1_clipped = (y1 < 0.0 or y1 > 1.0) y2_clipped = (y2 < 0.0 or y2 > 1.0) lineseg_dict[(v1, v2)] = [[nx1, ny1], [nx2, ny2], x1_wrapped, x2_wrapped, y1_clipped, y2_clipped] if (v1, v2) in lineseg_dict: if not ( rev ^ ccw ): v2, v1 = v1, v2 assert (v1, v2) not in c_point_linesegs[c_i] c_point_linesegs[c_i].append((v1, v2)) return vor, lineseg_dict, c_point_linesegs
#!/Users/simurgh/anaconda/bin/python import os import json import folium from folium import GeoJson from scipy.spatial import Voronoi, voronoi_plot_2d import matplotlib.pyplot as plt ixp_location = os.path.join('buildings.geojson') with open(ixp_location) as f: ixp = json.load(f) coor_list = [] for feature in ixp['features']: coor_list.append(feature['geometry']['coordinates']) kw = {'location': [48, -102], 'zoom_start': 3} m = folium.Map(**kw) GeoJson(ixp).add_to(m) vor = Voronoi(coor_list) vor_plot = voronoi_plot_2d(vor) #vor_plot.add_to(m) m.save(os.path.join('ixp-map.html'))
for seed in range(seeds): tiles, tilepoints = DualizeGridParallel(kmin, kmax, g, nj, seed) (a, b, c) = tiles.shape tilepoints2 = np.dot(tilepoints, sve) dist = np.linalg.norm(tilepoints2, axis=1) pts_ind = np.where(dist < rad / 2)[0] print 'calculating vertex distribution...seed', seed s = time() vor = Voronoi(tilepoints2) gc.collect() print 'vor done...', time() - s s = time() # Get Vertices temp = [vor.vertices[vor.regions[vor.point_region[x]]] for x in pts_ind] areas = [PolyAreaPt(r) for r in temp] round_areas = np.round(areas, 10) v_types = [
import numpy as np import matplotlib.pyplot as pl from scipy.spatial import Voronoi,voronoi_plot_2d # 31 holes xh=np.array([-48.993637046529095,-43.753369272237194,-43.17579606194892 ,-40.78616352201257 ,-30.849491348578386,-30.7672646156706 ,-29.372566636717583,-26.185054373083002,-23.979591836734695,-21.505414479595217,-20.87235597788844 ,-20.579072953029033,-17.59445383525972 ,-14.69227313566936 ,-6.933962264150935 ,-5.5424528301886795,-3.715184186882304 ,9.016607251543334 ,9.404407244526404 ,10.309973045822098 ,13.217173661917592 ,24.713907410034466 ,25.669362084456395 ,29.49011680143755 ,31.704851752021554 ,32.367475292003604 ,34.21170851657446 ,38.25780072182374 ,45.03732116939662 ,46.606019766397125 ,49.35983827493261]) yh=np.array([-36.4480247623806 ,-34.213807680788804,-27.373786637357966, 15.07214778146384 ,-20.785372063521777,-14.146690844397398, 19.179069688672126, 11.507796245719163, 49.42837193450884 ,-13.975486990941299, 34.93752459964086 ,-29.565907369514704, 11.955438263101364, 15.508605322874203,-26.686039982030536,-2.468913681219931 ,-24.400262342479337,-37.377870848465776,-13.767086211537539, 36.93420207530489 ,-42.92346040577172 , 11.88515518052511 ,-49.24684526689242 , 19.47046991268691 ,-11.1310531711475 , 44.81586145585473 ,-21.357137325049436,-34.61274344858849 ,-22.528444432925525,-46.57185548989793 , 26.800256871011605]) holes=np.transpose(np.array([xh,yh])) # Periodicity holes=np.vstack((holes,holes+[+100,0],holes+[-100,0],holes+[0,+100],holes+[0,-100],holes+[+100,+100],holes+[-100,-100],holes+[+100,-100],holes+[-100,+100])) # Form Voronoi diagram vor=Voronoi(holes) # Now plot Voronoi fig=voronoi_plot_2d(vor,show_vertices=True,line_colors='orange',line_width=2,line_alpha=0.6, point_size=2) pl.xlabel('$x/h_{film}$',size=16) pl.ylabel('$y/h_{film}$',size=16) ticks=np.linspace(-50,+50,5) pl.xticks(ticks) pl.yticks(ticks) pl.xlim(xmin=-50,xmax=+50) pl.ylim(ymin=-50,ymax=+50) pl.show() # Plot holes #fig,ax=pl.subplots() #ax.scatter(x=xh,y=yh,marker='o') #ax.set_xlabel('$x/h_{film}$',size=16) #ax.set_ylabel('$y/h_{film}$',size=16)
Dia = 3e-6 #checked r = Dia / 2 eta_oil = 920e-6 #wikipedia, checked eta_water = 1.002e-3 #wikipedia, checked theta = math.radians(130) #contact angle, Raynaert, 2006 sigma = 7.5e-2 #charge density, checked alpha_oil = 3.3e-4 #degree of dissosiation, checked, Aveyard 2002 epsilon_zero = 8.8542e-12 #permittivity of free space, checked epsilon_oil = 2.0 #relative dieelectric constant gamma_ow = 50e-3 #surface tension oil water, checked H = 10e-9 #undulation amplitude, Danov 2005, checked del_phi = math.radians(80) N = 144 # number of Particles L = float(18 * Dia) # box side length M = float(((4 * math.pi * r**3) / 3) * 1.055) # mass T0 = 293 # temperature (Kelvin) R = numpy.loadtxt('Equilibrated final position.txt', delimiter=',') x1 = R[:, 0] y1 = R[:, 1] c = Voronoi(R) voronoi_plot_2d(c) pl.scatter(x1, y1) pl.xlim((-L / 2, L / 2)) pl.ylim((-L / 2, L / 2)) pl.show()
def setFacetsLocs(self): NFacets = self.NFacets Npix = self.GD["Image"]["NPix"] Padding = self.GD["Facets"]["Padding"] self.Padding = Padding Npix, _ = EstimateNpix(float(Npix), Padding=1) self.Npix = Npix self.OutImShape = (self.nch, self.npol, self.Npix, self.Npix) RadiusTot = self.CellSizeRad * self.Npix / 2 self.RadiusTot = RadiusTot lMainCenter, mMainCenter = 0., 0. self.lmMainCenter = lMainCenter, mMainCenter self.CornersImageTot = np.array( [[lMainCenter - RadiusTot, mMainCenter - RadiusTot], [lMainCenter + RadiusTot, mMainCenter - RadiusTot], [lMainCenter + RadiusTot, mMainCenter + RadiusTot], [lMainCenter - RadiusTot, mMainCenter + RadiusTot]]) # MSName = self.GD["Data"]["MS"] # if ".txt" in MSName: # f = open(MSName) # Ls = f.readlines() # f.close() # MSName = [] # for l in Ls: # ll = l.replace("\n", "") # MSName.append(ll) # MSName = MSName[0] MSName = self.VS.ListMS[0].MSName SolsFile = self.GD["DDESolutions"]["DDSols"] if isinstance(SolsFile, list): SolsFile = self.GD["DDESolutions"]["DDSols"][0] if SolsFile and (not (".npz" in SolsFile)) and (not (".h5" in SolsFile)): Method = SolsFile ThisMSName = reformat.reformat(os.path.abspath(MSName), LastSlash=False) SolsFile = "%s/killMS.%s.sols.npz" % (ThisMSName, Method) # if "CatNodes" in self.GD.keys(): regular_grid = False if self.GD["Facets"]["CatNodes"] is not None: print >> log, "Taking facet directions from Nodes catalog: %s" % self.GD[ "Facets"]["CatNodes"] ClusterNodes = np.load(self.GD["Facets"]["CatNodes"]) ClusterNodes = ClusterNodes.view(np.recarray) raNode = ClusterNodes.ra decNode = ClusterNodes.dec lFacet, mFacet = self.CoordMachine.radec2lm(raNode, decNode) elif ".npz" in SolsFile: print >> log, "Taking facet directions from solutions file: %s" % SolsFile ClusterNodes = np.load(SolsFile)["ClusterCat"] ClusterNodes = ClusterNodes.view(np.recarray) raNode = ClusterNodes.ra decNode = ClusterNodes.dec lFacet, mFacet = self.CoordMachine.radec2lm(raNode, decNode) elif ".h5" in SolsFile: print >> log, "Taking facet directions from HDF5 solutions file: %s" % SolsFile H = tables.open_file(SolsFile) raNode, decNode = H.root.sol000.source[:]["dir"].T lFacet, mFacet = self.CoordMachine.radec2lm(raNode, decNode) H.close() del (H) else: print >> log, "Taking facet directions from regular grid" regular_grid = True CellSizeRad = (self.GD["Image"]["Cell"] / 3600.) * np.pi / 180 lrad = Npix * CellSizeRad * 0.5 NpixFacet = Npix / NFacets lfacet = NpixFacet * CellSizeRad * 0.5 lcenter_max = lrad - lfacet lFacet, mFacet, = np.mgrid[-lcenter_max:lcenter_max:(NFacets) * 1j, -lcenter_max:lcenter_max:(NFacets) * 1j] lFacet = lFacet.flatten() mFacet = mFacet.flatten() print >> log, " There are %i Jones-directions" % lFacet.size self.lmSols = lFacet.copy(), mFacet.copy() raSols, decSols = self.CoordMachine.lm2radec(lFacet.copy(), mFacet.copy()) self.radecSols = raSols, decSols NodesCat = np.zeros((raSols.size, ), dtype=[('ra', np.float), ('dec', np.float), ('l', np.float), ('m', np.float)]) NodesCat = NodesCat.view(np.recarray) NodesCat.ra = raSols NodesCat.dec = decSols # print>>log,"Facet RA %s"%raSols # print>>log,"Facet Dec %s"%decSols NodesCat.l = lFacet NodesCat.m = mFacet ## saving below # NodeFile = "%s.NodesCat.%snpy" % (self.GD["Output"]["Name"], "psf." if self.DoPSF else "") # print>> log, "Saving Nodes catalog in %s" % NodeFile # np.save(NodeFile, NodesCat) self.DicoImager = {} xy = np.zeros((lFacet.size, 2), np.float32) xy[:, 0] = lFacet xy[:, 1] = mFacet regFile = "%s.tessel0.reg" % self.ImageName NFacets = self.NFacets = lFacet.size rac, decc = self.MainRaDec VM = ModVoronoiToReg.VoronoiToReg(rac, decc) if NFacets > 2: vor = Voronoi(xy, furthest_site=False) regions, vertices = ModVoronoi.voronoi_finite_polygons_2d( vor, radius=1.) PP = Polygon.Polygon(self.CornersImageTot) LPolygon = [] ListNode = [] for region, iNode in zip(regions, range(NodesCat.shape[0])): ThisP = np.array(PP & Polygon.Polygon(np.array(vertices[region]))) if ThisP.size > 0: LPolygon.append(ThisP[0]) ListNode.append(iNode) NodesCat = NodesCat[np.array(ListNode)].copy() # ======= # LPolygon = [ # np.array(PP & Polygon.Polygon(np.array(vertices[region])))[0] # for region in regions] # >>>>>>> issue-255 elif NFacets == 1: l0, m0 = lFacet[0], mFacet[0] LPolygon = [self.CornersImageTot] # VM.ToReg(regFile,lFacet,mFacet,radius=.1) NodeFile = "%s.NodesCat.npy" % self.GD["Output"]["Name"] print >> log, "Saving Nodes catalog in %s" % NodeFile np.save(NodeFile, NodesCat) for iFacet, polygon0 in zip(range(len(LPolygon)), LPolygon): # polygon0 = vertices[region] P = polygon0.tolist() # VM.PolygonToReg(regFile,LPolygon,radius=0.1,Col="red") # stop ########################################### # SubDivide def GiveDiam(polygon): lPoly, mPoly = polygon.T l0 = np.max([lMainCenter - RadiusTot, lPoly.min()]) l1 = np.min([lMainCenter + RadiusTot, lPoly.max()]) m0 = np.max([mMainCenter - RadiusTot, mPoly.min()]) m1 = np.min([mMainCenter + RadiusTot, mPoly.max()]) dl = l1 - l0 dm = m1 - m0 diam = np.max([dl, dm]) return diam, (l0, l1, m0, m1) DiamMax = self.GD["Facets"]["DiamMax"] * np.pi / 180 # DiamMax=4.5*np.pi/180 DiamMin = self.GD["Facets"]["DiamMin"] * np.pi / 180 def ClosePolygon(polygon): P = polygon.tolist() polygon = np.array(P + [P[0]]) return polygon def GiveSubDivideRegions(polygonFacet, DMax): polygonFOV = self.CornersImageTot # polygonFOV=ClosePolygon(polygonFOV) PFOV = Polygon.Polygon(polygonFOV) # polygonFacet=ClosePolygon(polygonFacet) P0 = Polygon.Polygon(polygonFacet) P0Cut = Polygon.Polygon(P0 & PFOV) if P0Cut.nPoints() == 0: return [] polygonFacetCut = np.array(P0Cut[0]) # polygonFacetCut=ClosePolygon(polygonFacetCut) diam, (l0, l1, m0, m1) = GiveDiam(polygonFacetCut) if diam < DMax: return [polygonFacetCut] Nl = int((l1 - l0) / DMax) + 1 Nm = int((m1 - m0) / DMax) + 1 dl = (l1 - l0) / Nl dm = (m1 - m0) / Nm lEdge = np.linspace(l0, l1, Nl + 1) mEdge = np.linspace(m0, m1, Nm + 1) lc = (lEdge[0:-1] + lEdge[1::]) / 2 mc = (mEdge[0:-1] + mEdge[1::]) / 2 LPoly = [] Lc, Mc = np.meshgrid(lc, mc) Lc = Lc.ravel().tolist() Mc = Mc.ravel().tolist() DpolySquare = np.array([[-dl, -dm], [dl, -dm], [dl, dm], [-dl, dm] ]) * 0.5 for lc, mc in zip(Lc, Mc): polySquare = DpolySquare.copy( ) # ClosePolygon(DpolySquare.copy()) polySquare[:, 0] += lc polySquare[:, 1] += mc # polySquare=ClosePolygon(polySquare) P1 = Polygon.Polygon(polySquare) POut = (P0Cut & P1) if POut.nPoints() == 0: continue polyOut = np.array(POut[0]) # polyOut=ClosePolygon(polyOut) LPoly.append(polyOut) # pylab.clf() # x,y=polygonFacetCut.T # pylab.plot(x,y,color="blue") # x,y=polygonFacet.T # pylab.plot(x,y,color="blue",ls=":",lw=3) # x,y=np.array(PFOV[0]).T # pylab.plot(x,y,color="black") # x,y=polySquare.T # pylab.plot(x,y,color="green",ls=":",lw=3) # x,y=polyOut.T # pylab.plot(x,y,color="red",ls="--",lw=3) # pylab.xlim(-0.03,0.03) # pylab.ylim(-0.03,0.03) # pylab.draw() # pylab.show(False) # pylab.pause(0.5) return LPoly def PlotPolygon(P, *args, **kwargs): for poly in P: x, y = ClosePolygon(np.array(poly)).T pylab.plot(x, y, *args, **kwargs) LPolygonNew = [] for iFacet in xrange(len(LPolygon)): polygon = LPolygon[iFacet] ThisDiamMax = DiamMax SubReg = GiveSubDivideRegions(polygon, ThisDiamMax) LPolygonNew += SubReg regFile = "%s.FacetMachine.tessel.ReCut.reg" % self.ImageName # VM.PolygonToReg(regFile,LPolygonNew,radius=0.1,Col="green",labels=[str(i) for i in range(len(LPolygonNew))]) DicoPolygon = {} for iFacet in xrange(len(LPolygonNew)): DicoPolygon[iFacet] = {} poly = LPolygonNew[iFacet] DicoPolygon[iFacet]["poly"] = poly diam, (l0, l1, m0, m1) = GiveDiam(poly) DicoPolygon[iFacet]["diam"] = diam DicoPolygon[iFacet]["diamMin"] = np.min([(l1 - l0), (m1 - m0)]) xc, yc = np.mean(poly[:, 0]), np.mean(poly[:, 1]) DicoPolygon[iFacet]["xyc"] = xc, yc dSol = np.sqrt((xc - lFacet)**2 + (yc - mFacet)**2) DicoPolygon[iFacet]["iSol"] = np.where(dSol == np.min(dSol))[0] for iFacet in sorted(DicoPolygon.keys()): diam = DicoPolygon[iFacet]["diamMin"] # print iFacet,diam,DiamMin if diam < DiamMin: dmin = 1e6 xc0, yc0 = DicoPolygon[iFacet]["xyc"] HasClosest = False for iFacetOther in sorted(DicoPolygon.keys()): if iFacetOther == iFacet: continue iSolOther = DicoPolygon[iFacetOther]["iSol"] # print " ",iSolOther,DicoPolygon[iFacet]["iSol"] if iSolOther != DicoPolygon[iFacet]["iSol"]: continue xc, yc = DicoPolygon[iFacetOther]["xyc"] d = np.sqrt((xc - xc0)**2 + (yc - yc0)**2) if d < dmin: dmin = d iFacetClosest = iFacetOther HasClosest = True if (HasClosest): print >> log, "Merging facet #%i to #%i" % (iFacet, iFacetClosest) P0 = Polygon.Polygon(DicoPolygon[iFacet]["poly"]) P1 = Polygon.Polygon(DicoPolygon[iFacetClosest]["poly"]) P2 = (P0 | P1) POut = [] for iP in xrange(len(P2)): POut += P2[iP] poly = np.array(POut) hull = ConvexHull(poly) Contour = np.array([ hull.points[hull.vertices, 0], hull.points[hull.vertices, 1] ]) poly2 = Contour.T del (DicoPolygon[iFacet]) DicoPolygon[iFacetClosest]["poly"] = poly2 DicoPolygon[iFacetClosest]["diam"] = GiveDiam(poly2)[0] DicoPolygon[iFacetClosest]["xyc"] = np.mean( poly2[:, 0]), np.mean(poly2[:, 1]) # stop LPolygonNew = [] for iFacet in sorted(DicoPolygon.keys()): # if DicoPolygon[iFacet]["diam"]<DiamMin: # print>>log, ModColor.Str(" Facet #%i associated to direction #%i is too small, removing it"%(iFacet,DicoPolygon[iFacet]["iSol"])) # continue LPolygonNew.append(DicoPolygon[iFacet]["poly"]) # for iFacet in range(len(regions)): # polygon=LPolygon[iFacet] # ThisDiamMax=DiamMax # while True: # SubReg=GiveSubDivideRegions(polygon,ThisDiamMax) # if SubReg==[]: # break # Diams=[GiveDiam(poly)[0] for poly in SubReg] # if np.min(Diams)>DiamMin: break # ThisDiamMax*=1.1 # LPolygonNew+=SubReg # print regFile = "%s.tessel.%sreg" % (self.GD["Output"]["Name"], "psf." if self.DoPSF else "") # labels=["[F%i.C%i]"%(i,DicoPolygon[i]["iSol"]) for i in range(len(LPolygonNew))] # VM.PolygonToReg(regFile,LPolygonNew,radius=0.1,Col="green",labels=labels) # VM.PolygonToReg(regFile,LPolygonNew,radius=0.1,Col="green") # pylab.clf() # x,y=LPolygonNew[11].T # pylab.plot(x,y) # pylab.draw() # pylab.show() # stop ########################################### NFacets = len(LPolygonNew) NJonesDir = NodesCat.shape[0] self.JonesDirCat = np.zeros( (NodesCat.shape[0], ), dtype=[('Name', '|S200'), ('ra', np.float), ('dec', np.float), ('SumI', np.float), ("Cluster", int), ("l", np.float), ("m", np.float), ("I", np.float)]) self.JonesDirCat = self.JonesDirCat.view(np.recarray) self.JonesDirCat.I = 1 self.JonesDirCat.SumI = 1 self.JonesDirCat.ra = NodesCat.ra self.JonesDirCat.dec = NodesCat.dec self.JonesDirCat.l = NodesCat.l self.JonesDirCat.m = NodesCat.m self.JonesDirCat.Cluster = range(NJonesDir) print >> log, "Sizes (%i facets):" % (self.JonesDirCat.shape[0]) print >> log, " - Main field : [%i x %i] pix" % (self.Npix, self.Npix) l_m_Diam = np.zeros((NFacets, 4), np.float32) l_m_Diam[:, 3] = np.arange(NFacets) Np = 10000 D = {} for iFacet in xrange(NFacets): D[iFacet] = {} polygon = LPolygonNew[iFacet] D[iFacet]["Polygon"] = polygon lPoly, mPoly = polygon.T ThisDiam, (l0, l1, m0, m1) = GiveDiam(polygon) # ############################### # # Find barycenter of polygon # X=(np.random.rand(Np))*ThisDiam+l0 # Y=(np.random.rand(Np))*ThisDiam+m0 # XY = np.dstack((X, Y)) # XY_flat = XY.reshape((-1, 2)) # mpath = Path( polygon ) # XY = np.dstack((X, Y)) # XY_flat = XY.reshape((-1, 2)) # mask_flat = mpath.contains_points(XY_flat) # mask=mask_flat.reshape(X.shape) # ############################### ThisPolygon = Polygon.Polygon(polygon) lc, mc = ThisPolygon.center() dl = np.max(np.abs([l0 - lc, l1 - lc])) dm = np.max(np.abs([m0 - mc, m1 - mc])) ############################### # lc=np.sum(X*mask)/np.sum(mask) # mc=np.sum(Y*mask)/np.sum(mask) # dl=np.max(np.abs(X[mask==1]-lc)) # dm=np.max(np.abs(Y[mask==1]-mc)) diam = 2 * np.max([dl, dm]) ###################### # lc=(l0+l1)/2. # mc=(m0+m1)/2. # dl=l1-l0 # dm=m1-m0 # diam=np.max([dl,dm]) l_m_Diam[iFacet, 0] = lc l_m_Diam[iFacet, 1] = mc l_m_Diam[iFacet, 2] = diam self.SpacialWeigth = {} self.DicoImager = {} # sort facets by size, unless we're in regular grid mode if not regular_grid: indDiam = np.argsort(l_m_Diam[:, 2])[::-1] l_m_Diam = l_m_Diam[indDiam] for iFacet in xrange(l_m_Diam.shape[0]): self.DicoImager[iFacet] = {} self.DicoImager[iFacet]["Polygon"] = D[l_m_Diam[iFacet, 3]]["Polygon"] x0 = round(l_m_Diam[iFacet, 0] / self.CellSizeRad) y0 = round(l_m_Diam[iFacet, 1] / self.CellSizeRad) if x0 % 2 == 0: x0 += 1 if y0 % 2 == 0: y0 += 1 l0 = x0 * self.CellSizeRad m0 = y0 * self.CellSizeRad diam = round( l_m_Diam[iFacet, 2] / self.CellSizeRad) * self.CellSizeRad # self.AppendFacet(iFacet,l0,m0,diam) self.AppendFacet(iFacet, l0, m0, diam) # self.MakeMasksTessel() NpixMax = np.max([ self.DicoImager[iFacet]["NpixFacet"] for iFacet in sorted(self.DicoImager.keys()) ]) NpixMaxPadded = np.max([ self.DicoImager[iFacet]["NpixFacetPadded"] for iFacet in sorted(self.DicoImager.keys()) ]) self.PaddedGridShape = (1, 1, NpixMaxPadded, NpixMaxPadded) self.FacetShape = (1, 1, NpixMax, NpixMax) dmin = 1 for iFacet in xrange(len(self.DicoImager)): l, m = self.DicoImager[iFacet]["l0m0"] d = np.sqrt(l**2 + m**2) if d < dmin: dmin = d iCentralFacet = iFacet self.iCentralFacet = iCentralFacet self.NFacets = len(self.DicoImager) # regFile="%s.tessel.reg"%self.GD["Output"]["Name"] labels = [(self.DicoImager[i]["lmShift"][0], self.DicoImager[i]["lmShift"][1], "[F%i_S%i]" % (i, self.DicoImager[i]["iSol"])) for i in xrange(len(LPolygonNew))] VM.PolygonToReg(regFile, LPolygonNew, radius=0.1, Col="green", labels=labels) self.WriteCoordFacetFile() self.FacetDirections = set([ self.DicoImager[iFacet]["RaDec"] for iFacet in range(len(self.DicoImager)) ]) #DicoName = "%s.DicoFacet" % self.GD["Images"]["ImageName"] DicoName = "%s.%sDicoFacet" % (self.GD["Output"]["Name"], "psf." if self.DoPSF else "") # Find the minimum l,m in the facet (for decorrelation calculation) for iFacet in self.DicoImager.keys(): #Create smoothned facet tessel mask: Npix = self.DicoImager[iFacet]["NpixFacetPadded"] l0, l1, m0, m1 = self.DicoImager[iFacet]["lmExtentPadded"] X, Y = np.mgrid[l0:l1:Npix / 10 * 1j, m0:m1:Npix / 10 * 1j] XY = np.dstack((X, Y)) XY_flat = XY.reshape((-1, 2)) vertices = self.DicoImager[iFacet]["Polygon"] mpath = Path(vertices) # the vertices of the polygon mask_flat = mpath.contains_points(XY_flat) mask = mask_flat.reshape(X.shape) mpath = Path(self.CornersImageTot) mask_flat2 = mpath.contains_points(XY_flat) mask2 = mask_flat2.reshape(X.shape) mask[mask2 == 0] = 0 R = np.sqrt(X**2 + Y**2) R[mask == 0] = 1e6 indx, indy = np.where(R == np.min(R)) lmin, mmin = X[indx[0], indy[0]], Y[indx[0], indy[0]] self.DicoImager[iFacet]["lm_min"] = lmin, mmin print >> log, "Saving DicoImager in %s" % DicoName MyPickle.Save(self.DicoImager, DicoName)
def _initialize(self, x, y, reorient_links=True): """ Creates an unstructured grid around the given (x,y) points. """ x, y = np.asarray(x, dtype=float), np.asarray(y, dtype=float) if x.size != y.size: raise ValueError('x and y arrays must have the same size') # Make a copy of the points in a 2D array (useful for calls to geometry # routines, but takes extra memory space). xy_of_node = np.hstack((x.reshape((-1, 1)), y.reshape((-1, 1)))) self._xy_of_node = sort_points_by_x_then_y(xy_of_node) # NODES AND CELLS: Set up information pertaining to nodes and cells: # - number of nodes # - node x, y coordinates # - default boundary status # - interior and boundary nodes # - nodes associated with each cell and active cell # - cells and active cells associated with each node # (or BAD_VALUE_INDEX if none) # # Assumptions we make here: # - all interior (non-perimeter) nodes have cells (this should be # guaranteed in a Delaunay triangulation, but there may be # special cases) # - all cells are active (later we'll build a mechanism for the user # specify a subset of cells as active) # [self._node_status, self._core_nodes, self._boundary_nodes] = \ self._find_perimeter_nodes_and_BC_set(self._xy_of_node) [self._cell_at_node, self._node_at_cell] = \ self._node_to_cell_connectivity(self._node_status, self.number_of_cells) active_cell_at_node = self.cell_at_node[self.core_nodes] # ACTIVE CELLS: Construct Voronoi diagram and calculate surface area of # each active cell. vor = Voronoi(self._xy_of_node) self.vor = vor self._area_of_cell = np.zeros(self.number_of_cells) for node in self._node_at_cell: xv = vor.vertices[vor.regions[vor.point_region[node]], 0] yv = vor.vertices[vor.regions[vor.point_region[node]], 1] self._area_of_cell[self.cell_at_node[node]] = (simple_poly_area( xv, yv)) # LINKS: Construct Delaunay triangulation and construct lists of link # "from" and "to" nodes. (node_at_link_tail, node_at_link_head, _, self._face_width) = \ self._create_links_and_faces_from_voronoi_diagram(vor) self._status_at_link = np.full(len(node_at_link_tail), INACTIVE_LINK, dtype=int) self._nodes_at_link = np.hstack((node_at_link_tail.reshape( (-1, 1)), node_at_link_head.reshape((-1, 1)))) # Sort them by midpoint coordinates self._sort_links_by_midpoint() # Optionally re-orient links so that they all point within upper-right # semicircle if reorient_links: self._reorient_links_upper_right() # ACTIVE LINKS: Create list of active links, as well as "from" and "to" # nodes of active links. self._reset_link_status_list() # NODES & LINKS: IDs and directions of links at each node self._create_links_and_link_dirs_at_node() # LINKS: set up link unit vectors and node unit-vector sums self._create_link_unit_vectors()
def _generate_throats(self): r""" Generate the throats connections """ self._logger.info(sys._getframe().f_code.co_name + ": Define connections between pores") Np = self._Np pts = self['pore.coords'] #Generate 6 dummy domains to pad onto each face of real domain #This prevents surface pores from making long range connections to each other Lx = self._Lx Ly = self._Ly Lz = self._Lz #Reflect in X = Lx and 0 Pxp = pts.copy() Pxp[:, 0] = (2 * Lx - Pxp[:, 0]) Pxm = pts.copy() Pxm[:, 0] = Pxm[:, 0] * (-1) #Reflect in Y = Ly and 0 Pyp = pts.copy() Pyp[:, 1] = (2 * Ly - Pxp[:, 1]) Pym = pts.copy() Pym[:, 1] = Pxm[:, 1] * (-1) #Reflect in Z = Lz and 0 Pzp = pts.copy() Pzp[:, 2] = (2 * Lz - Pxp[:, 2]) Pzm = pts.copy() Pzm[:, 2] = Pxm[:, 2] * (-1) #Add dummy domains to real domain pts = np.vstack((pts, Pxp, Pxm, Pyp, Pym, Pzp, Pzm)) #Order important for boundary logic #Perform tessellation self._logger.debug(sys._getframe().f_code.co_name + ": Beginning tessellation") Tri = sptl.Delaunay(pts) self._logger.debug(sys._getframe().f_code.co_name + ": Converting tessellation to adjacency matrix") adjmat = sprs.lil_matrix((Np, Np), dtype=int) for i in sp.arange(0, sp.shape(Tri.simplices)[0]): #Keep only simplices that are fully in real domain #this used to be vectorize, but it stopped working...change in scipy? for j in Tri.simplices[i]: if j < Np: adjmat[j, Tri.simplices[i][Tri.simplices[i] < Np]] = 1 #Remove duplicate (lower triangle) and self connections (diagonal) #and convert to coo adjmat = sprs.triu(adjmat, k=1, format="coo") self._logger.debug(sys._getframe().f_code.co_name + ": Conversion to adjacency matrix complete") self['throat.conns'] = sp.vstack((adjmat.row, adjmat.col)).T self['pore.all'] = np.ones(len(self['pore.coords']), dtype=bool) self['throat.all'] = np.ones(len(self['throat.conns']), dtype=bool) #New code to identify boundary pores - those that connect to pores inside and outside original set of pores boundary_pore_list = [] for i in sp.arange(0, sp.shape(Tri.simplices)[0]): pores_in = Tri.simplices[i] < Np # Pores in the original domain if (sum(pores_in) >= 1) and (sum(pores_in) < len(pores_in)): for j in range(len(Tri.simplices[i])): if pores_in[j] == True: pore_id = Tri.simplices[i][j] if pore_id not in boundary_pore_list: boundary_pore_list.append(pore_id) vor_bounds = sp.asarray(boundary_pore_list) self.set_info(pores=vor_bounds, label='inner_boundary') self.set_info(pores='all', label='internal') self.set_info(throats='all', label='internal') # Do Voronoi diagram - creating voronoi polyhedra around each pore and save vertex information vor = Voronoi(pts) all_verts = sp.ndarray(Np, dtype=object) for i, polygon in enumerate(vor.point_region[0:Np]): if -1 not in vor.regions[polygon]: all_verts[i] = np.around(vor.vertices[vor.regions[polygon]], 10) else: all_verts[i] = "unbounded" self['pore.vertices'] = all_verts self._logger.debug(sys._getframe().f_code.co_name + ": End of method")
ys.append(y) xavg.append(average(x)) yavg.append(average(y)) def plot_points(repr): xlim(xrng) ylim(yrng) for i in range(len(N)): if repr: text(xavg[i] + 0.1, yavg[i] + 0.1, "representative of class%d" % i) plot(xavg[i], yavg[i], "bo", color='yellow') scatter(xs[i], ys[i], s=60, c=color[i]) voronoi_plot_2d(Voronoi(array([xavg, yavg]).T)) plot_points(True) savefig("fig1-4-1.png") clf() plot_points(True) X, Y = meshgrid(arange(xrng[0], xrng[1], 0.1), arange(yrng[0], yrng[1], 0.1)) diff = [((X - xavg[i])**2 + (Y - yavg[i])**2) / sigma[i]**2 for i in range(len(N))] contour(X, Y, (diff[0] - diff[1]), [0]) contour(X, Y, (diff[0] - diff[2]), [0]) contour(X, Y, (diff[1] - diff[2]), [0]) savefig("fig1-4-2.png")
def get_centerline(geom, segmentize_maxlen=0.5, max_points=3000, simplification=0.05, smooth_sigma=5, max_paths=5): """ Return centerline from geometry. Parameters: ----------- geom : shapely Polygon or MultiPolygon segmentize_maxlen : Maximum segment length for polygon borders. (default: 0.5) max_points : Number of points per geometry allowed before simplifying. (default: 3000) simplification : Simplification threshold. (default: 0.05) smooth_sigma : Smoothness of the output centerlines. (default: 5) max_paths : Number of longest paths used to create the centerlines. (default: 5) Returns: -------- geometry : LineString or MultiLineString Raises: ------- CenterlineError : if centerline cannot be extracted from Polygon CenterlineError : if input geometry is not Polygon or MultiPolygon """ logger.debug("geometry type %s", geom.geom_type) if geom.geom_type == "Polygon": # segmentized Polygon outline outline = _segmentize(geom.exterior, segmentize_maxlen) logger.debug("outline: %s", outline) # simplify segmentized geometry if necessary and get points outline_points = outline.coords simplification_updated = simplification while len(outline_points) > max_points: # if geometry is too large, apply simplification until geometry # is simplified enough (indicated by the "max_points" value) simplification_updated += simplification outline_points = outline.simplify(simplification_updated).coords logger.debug("simplification used: %s", simplification_updated) logger.debug("simplified points: %s", MultiPoint(outline_points)) # calculate Voronoi diagram and convert to graph but only use points # from within the original polygon try: vor = Voronoi(outline_points) graph = _graph_from_voronoi(vor, geom) except Exception: logger.debug("Voronoi diagram could not be created") raise CenterlineError("Voronoi diagram could not be created") logger.debug("voronoi diagram: %s", _multilinestring_from_voronoi(vor, geom)) # determine longest path between all end nodes from graph end_nodes = _get_end_nodes(graph) if len(end_nodes) < 2: logger.debug("Polygon has too few points") raise CenterlineError("Polygon has too few points") logger.debug("get longest path from %s end nodes", len(end_nodes)) longest_paths = _get_longest_paths(end_nodes, graph, max_paths) if not longest_paths: logger.debug("no paths found between end nodes") raise CenterlineError("no paths found between end nodes") if logger.getEffectiveLevel() <= 10: logger.debug("longest paths:") for path in longest_paths: logger.debug(LineString(vor.vertices[path])) # get least curved path from the longest paths, smooth and # return as LineString centerline = _smooth_linestring( LineString(vor.vertices[_get_least_curved_path( longest_paths, vor.vertices)]), smooth_sigma) logger.debug("centerline: %s", centerline) logger.debug("return linestring") return centerline elif geom.geom_type == "MultiPolygon": logger.debug("MultiPolygon found with %s sub-geometries", len(geom)) # get centerline for each part Polygon and combine into MultiLineString sub_centerlines = [] for subgeom in geom: try: sub_centerline = get_centerline(subgeom, segmentize_maxlen, max_points, simplification, smooth_sigma) sub_centerlines.append(sub_centerline) except CenterlineError as e: logger.debug("subgeometry error: %s", e) # for MultPolygon, only raise CenterlineError if all subgeometries fail if sub_centerlines: return MultiLineString(sub_centerlines) else: raise CenterlineError("all subgeometries failed") else: raise CenterlineError( "Geometry type must be Polygon or MultiPolygon, not %s" % geom.geom_type)
colors.pop('k') print(colors) C1 = [-5, -2] + .8 * np.random.randn(avgPoints * 2, 2) C4 = [-2, 3] + .3 * np.random.randn(avgPoints // 5, 2) C3 = [1, -2] + .2 * np.random.randn(avgPoints * 5, 2) C5 = [3, -2] + 1.6 * np.random.randn(avgPoints, 2) C2 = [4, -1] + .1 * np.random.randn(avgPoints // 2, 2) C6 = [5, 6] + 2 * np.random.randn(avgPoints, 2) X = np.vstack((C1, C2, C3, C4, C5, C6)) fig, ((plt1, plt2, plt3), (plt4, plt5, plt6)) = plt.subplots(2, 3, figsize=(15, 9)) vor = Voronoi(X) voronoi_plot_2d(vor) plt1.set_title('Generated data') plt1.plot(C1[:, 0], C1[:, 1], 'b.', alpha=0.3) plt1.plot(C2[:, 0], C2[:, 1], 'r.', alpha=0.3) plt1.plot(C3[:, 0], C3[:, 1], 'g.', alpha=0.3) plt1.plot(C4[:, 0], C4[:, 1], 'c.', alpha=0.3) plt1.plot(C5[:, 0], C5[:, 1], 'm.', alpha=0.3) plt1.plot(C6[:, 0], C6[:, 1], 'y.', alpha=0.3) NN = NearestNeighbors(n_neighbors=np.log(X.size).astype(int)).fit(X) distances, indices = NN.kneighbors(X) plt2.set_title('eps elbow') plt2.plot(np.sort(distances[:, distances.shape[1] - 1]),
def pdf_voronoi_boundary(geneID, coord, count, classLabel, p, fileName, fdr=False, point_size=5, line_colors="k", class_line_width=2.5, line_width=0.5, line_alpha=1.0, **kw): ''' save spatial expression as voronoi tessellation to pdf highlight boundary between classes. :param file: geneID; spatial coordinates shape (n, 2); normalized count: shape (n); predicted cell class calls shape (n); prediction p-value; pdf fileName; fdr=False; line_colors = 'k'; class_line_width = 3; line_width = 0.5; line_alpha = 1.0 ''' points = coord count = count newLabels = classLabel # first estimate mean distance between points-- p_dist = cdist(points, points) p_dist[p_dist == 0] = np.max(p_dist, axis=0)[0] norm_dist = np.mean(np.min(p_dist, axis=0)) # find points at edge, add three layers of new points x_min = np.min(points, axis=0)[0] - 3 * norm_dist y_min = np.min(points, axis=0)[1] - 3 * norm_dist x_max = np.max(points, axis=0)[0] + 3 * norm_dist y_max = np.max(points, axis=0)[1] + 3 * norm_dist n_x = int((x_max - x_min) / norm_dist) + 1 n_y = int((y_max - y_min) / norm_dist) + 1 # create a mesh x = np.linspace(x_min, x_max, n_x) y = np.linspace(y_min, y_max, n_y) xv, yv = np.meshgrid(x, y) # now select points outside of hull, and merge hull = Delaunay(points) grid_points = np.hstack((xv.reshape(-1, 1), yv.reshape(-1, 1))) pad_points = grid_points[np.where(hull.find_simplex(grid_points) < 0)[0]] pad_dist = cdist(pad_points, points) pad_points = pad_points[np.where(np.min(pad_dist, axis=1) > norm_dist)[0]] all_points = np.vstack((points, pad_points)) ori_len = points.shape[0] vor = Voronoi(all_points) if kw.get("show_points", True): plt.plot(points[0:ori_len, 0], points[0:ori_len, 1], ".", markersize=point_size) patches = [] # but we onl use the original points fot plotting for i in np.arange(ori_len): good_ver = vor.vertices[vor.regions[vor.point_region[i]]] polygon = Polygon(good_ver, True) patches.append(polygon) pc = PatchCollection(patches, cmap=cm.PiYG, alpha=1) pc.set_array(np.array(count)) plt.gca().add_collection(pc) # for loop for plotting is slow, consider to vectorize to speedup # doesn;t mater for now unless you have many point or genes finite_segments = [] boundary_segments = [] for kk, ii in vor.ridge_dict.items(): if kk[0] < ori_len and kk[1] < ori_len: if newLabels[kk[0]] != newLabels[kk[1]]: boundary_segments.append(vor.vertices[ii]) else: finite_segments.append(vor.vertices[ii]) plt.gca().add_collection( LineCollection(boundary_segments, colors="k", lw=class_line_width, alpha=1, linestyles="solid")) plt.gca().add_collection( LineCollection(finite_segments, colors=line_colors, lw=line_width, alpha=line_alpha, linestyle="solid")) plt.xlim(x_min + 1 * norm_dist, x_max - 1 * norm_dist) plt.ylim(y_min + 1 * norm_dist, y_max - 1 * norm_dist) # also remember to add color bar plt.colorbar(pc) if fdr: titleText = geneID + '\n' + 'fdr: ' + str("{:.2e}".format(p)) else: titleText = geneID + '\n' + 'p_value: ' + str("{:.2e}".format(p)) titleText = kw.get("set_title", titleText) fontsize = kw.get("fontsize", 12) plt.title(titleText, fontname="Arial", fontsize=fontsize) plt.axis('off') # plt.xlabel('X coordinate') # plt.ylabel('Y coordinate') if fileName != None: plt.savefig(fileName) else: print('ERROR! Please supply a file name.')
def __init__(self, hydrants): self.vor = Voronoi(hydrants, incremental=True) self.poly = Polygon([(float(x.split(', ')[0]), float(x.split(', ')[1])) for x in open('coords.txt').read().split('\n')[:-1]])
def Vonoroi_SH(self, mesh_size=0.1): """ Generates a equally spaced mesh on the Solar Horizont (SH). Computes the Voronoi diagram from a set of points given by pairs of (azimuth, zenit) values. This discretization completely covers all the Sun positions. The smaller mesh size, the better resolution obtained. It is important to note that this heavily affects the performance. The generated information is stored in: * **.t2vor_map** (*ndarray*): Mapping between time vector and the Voronoi diagram. * **.vor_freq** (*ndarray*): Number of times a Sun position is inside each polygon in the Voronoi diagram. * **.vor_surf** (*``pyny.Surface``*): Voronoi diagram. * **.vor_centers** (*ndarray`*): Mass center of the ``pyny.Polygons`` that form the Voronoi diagram. :param mesh_size: Mesh size for the square discretization of the Solar Horizont. :type mesh_size: float (in radians) :param plot: If True, generates a visualization of the Voronoi diagram. :type plot: bool :returns: None .. note:: In future versions this discretization will be improved substantially. For now, it is quite rigid and only admits square discretization. """ from scipy.spatial import Voronoi from pyny3d.utils import sort_numpy state = pyny.Polygon.verify pyny.Polygon.verify = False # Sort and remove NaNs xy_sorted, order_back = sort_numpy(self.azimuth_zenit, col=1, order_back=True) # New grid x1 = np.arange(-np.pi, np.pi, mesh_size) y1 = np.arange(-mesh_size*2, np.pi/2+mesh_size*2, mesh_size) x1, y1 = np.meshgrid(x1, y1) centers = np.array([x1.ravel(), y1.ravel()]).T # Voronoi vor = Voronoi(centers) # Setting the SH polygons pyny_polygons = [pyny.Polygon(vor.vertices[v], False) for v in vor.regions[1:] if len(v) > 3] raw_surf = pyny.Surface(pyny_polygons) # Classify data into the polygons discretization map_ = raw_surf.classify(xy_sorted, edge=True, col=1, already_sorted=True) map_ = map_[order_back] # Selecting polygons with points inside vor = [] count = [] for i, poly_i in enumerate(np.unique(map_)[1:]): vor.append(raw_surf[poly_i]) bool_0 = map_==poly_i count.append(bool_0.sum()) map_[bool_0] = i # Storing the information self.t2vor_map = map_ self.vor_freq = np.array(count) self.vor_surf = pyny.Surface(vor) self.vor_centers = np.array([poly.get_centroid()[:2] for poly in self.vor_surf]) pyny.Polygon.verify = state