import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt from scipy.stats import gaussian_kde from scipy.spatial.distance import cdist import copy class create(): def __init__(self): """ data is the x and y coordinate of data.pos contours is the edge points f is the kernel density value levels is the levels for contours x_range is the range of x label y_range is the range of y label """ self.data = [] self.contours = [] self.f = [] self.levels = [] self.x_range = [] self.y_range = [] def data_pre(self, data_name): with open(data_name, 'r') as f: lines = f.readlines() L_en=len(lines) lines= lines[1:L_en] data = [] for line in lines: x, y,z,t = line.strip().split("\t") data.append(list(map(float, [x,y]))) data = np.array(data) self.data = data self.x_range = [min(data[:, 0]), max(data[:,0])] self.y_range = [min(data[:, 1]), max(data[:,1])] def contours_pre(self, level_nums, gWeight): x = self.data[:, 0] y = self.data[:, 1] # 使用scipy库中的gaussian_kde函数计算密度估计 kde = gaussian_kde(self.data.T) # 生成网格点坐标 xx, yy = np.mgrid[x.min():x.max():200j, y.min():y.max():200j] positions = np.vstack([xx.ravel(), yy.ravel()]) # 计算网格点上的密度估计值 f = np.reshape(kde(positions).T, xx.shape) # 绘制等高线图 levels = [] for i in range(level_nums): levels.append(f.max() - (level_nums - i - 1) * (f.max() - f.min()) / gWeight) self.levels = levels contours = plt.contour(xx, yy, f, levels=[levels[0], levels[level_nums - 1]], cmap='coolwarm', alpha=0) plt.close() self_contours = [] for i in range(len(contours.allsegs[0])): self_contours += contours.allsegs[0][i].tolist() for i in range(len(self_contours)): if self_contours[i] not in self.contours: self.contours += [self_contours[i]] self.f = f class well_to_edge(): def __init__(self): """ name is used to store the well names type is the types of the wells position is the coordinates of wells min_distance is the minimum distances between wells and edge welltoedge_points is the points responding to the min_distance angle is the angles between the shortest distance direction vector from the well to the edge and the positive direction of the y-axis during clockwise rotation; wells_num: the number of wells """ self.name = [] self.type = [] self.position = [] self.min_distance = [] self.welltoedge_points = [] self.angle = [] self.wells_num = 0 def wells_name_and_position(self, wells_name): # 读取井位信息 with open(wells_name, 'r') as f_j: j_ing = f_j.readlines() points = [] typee = [] namee = [] for line in j_ing: x, y, type, name = line.strip().split("\t") points.append(list(map(float, [x, y]))) typee.append(list(map(int, [type]))) namee.append(name.split('\n')) self.position = points self.name = namee self.type = typee self.wells_num = len(points) def welltoedge_distance(self, contour_points): min_distance = [] contours_p=[] angles=[] wells_num = self.wells_num points = self.position # 定义待计算距离的点 for i in range(wells_num): point = np.array([points[i][0], points[i][1]]) # 计算点到等高线上所有点之间的距离 distances = cdist(point.reshape(1, -1), contour_points) # 取距离的最小值 min_distance.append(distances.min()) # 记录最短距离对应的点 for ii in range(distances.size): if distances[0][ii] == min_distance[-1]: contours_p.append(contour_points[ii]) # 计算角度(y轴为正北方向) direct = contours_p[-1] - point if direct[0] < 0: angles.append(360-np.arccos(np.dot(direct, np.array(([0, 1]))) / np.linalg.norm( direct)) / np.pi * 180) else: angles.append(np.arccos(np.dot(direct, np.array(([0, 1]))) / np.linalg.norm( direct)) / np.pi * 180) self.min_distance = min_distance self.welltoedge_points = contours_p self.angle = angles