You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
13 KiB
Python
277 lines
13 KiB
Python
2 years ago
|
# -*- coding: utf-8 -*-
|
||
|
import sys
|
||
|
from PySide6.QtWidgets import QApplication, QMainWindow, QGraphicsView, QFileDialog, QColorDialog
|
||
|
from PySide6.QtUiTools import QUiLoader
|
||
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||
|
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
|
||
|
from matplotlib.figure import Figure
|
||
|
import matplotlib.pyplot as plt
|
||
|
from PySide6.QtWidgets import QVBoxLayout
|
||
|
import CREAT
|
||
|
import numpy as np
|
||
|
import matplotlib as mpl
|
||
|
from matplotlib.path import Path
|
||
|
from matplotlib.patches import Patch
|
||
|
from PySide6.QtGui import QPalette
|
||
|
import random
|
||
|
# plt.legend(prop={'family': 'SimHei', 'size': 15})
|
||
|
|
||
|
|
||
|
class MainWindow(QMainWindow):
|
||
|
def __init__(self):
|
||
|
super().__init__()
|
||
|
self.toolbar = None
|
||
|
self.canvas = None
|
||
|
self.file_paths = []
|
||
|
self.get_color = lambda n: list(map(lambda i: "#" + "%06x" % random.randint(0, 0xFFFFFF),range(n)))
|
||
|
self.color = self.get_color(100) # 图例颜色选择值
|
||
|
self.colorbar = 'jet'
|
||
|
self.num = len(self.color) # 记录选择颜色的次数
|
||
|
self.oilwell_color = 'k'
|
||
|
self.waterwell_color = 'k'
|
||
|
self.chose = 0
|
||
|
self.num = 0
|
||
|
# 加载UI文件
|
||
|
self.ui = QUiLoader().load('QT/main_2.ui')
|
||
|
self.color_bar()
|
||
|
self.ui.legend_color.clicked.connect(self.legend_color_chose) # 选择图例颜色
|
||
|
self.ui.colorbar_chose.currentTextChanged.connect(self.update_colorbar) # 更新colorbar
|
||
|
self.ui.chose_oilwell_color.clicked.connect(lambda: self.oil_well_color()) # 选择油井颜色
|
||
|
self.ui.chose_oilwell_color.clicked.connect(lambda: self.plot_density()) # 更新油井颜色
|
||
|
self.ui.chose_waterwell_color.clicked.connect(lambda: self.water_well_color()) # 选择水井颜色
|
||
|
self.ui.chose_waterwell_color.clicked.connect(lambda: self.plot_density()) # 更新水井颜色
|
||
|
# 更新图窗
|
||
|
self.ui.graphicsView.repaint()
|
||
|
self.ui.graphicsView.update()
|
||
|
self.graphics_layout = QVBoxLayout(self.ui.graphicsView)
|
||
|
|
||
|
self.ui.chose_datafile_button.clicked.connect(self.choose_datafile)
|
||
|
|
||
|
self.ui.chose_wellfile_button.clicked.connect(self.choose_wellfile)
|
||
|
|
||
|
# 绘制或清除数据和画布
|
||
|
self.ui.clear_data.clicked.connect(lambda: self.clear_data())
|
||
|
|
||
|
# 绘图设置中心比例
|
||
|
self.ui.center_scale.clicked.connect(lambda: self.center_scale())
|
||
|
self.ui.center_scale.clicked.connect(lambda: self.plot_density())
|
||
|
self.ui.level_chose.valueChanged.connect(lambda: self.plot_density())
|
||
|
self.ui.gWeight_chose.valueChanged.connect(lambda: self.plot_density())
|
||
|
|
||
|
def self_levels(self):
|
||
|
self.levels = self.ui.level_chose.value() # 选择层参数
|
||
|
self.plot_density()
|
||
|
|
||
|
def self_gWeight(self):
|
||
|
self.gWeight = self.self.ui.gWeight_chose.value()
|
||
|
self.plot_density()
|
||
|
|
||
|
def scene_fig(self):
|
||
|
fig = Figure()
|
||
|
# 在Figure对象中添加子图
|
||
|
ax = fig.add_subplot(111)
|
||
|
return fig, ax
|
||
|
|
||
|
def canvas_adjust(self, fig):
|
||
|
if self.canvas is not None:
|
||
|
# 从布局中删除旧的 canvas 和 toolbar
|
||
|
item = self.graphics_layout.takeAt(0)
|
||
|
while item:
|
||
|
widget = item.widget()
|
||
|
if widget:
|
||
|
widget.setParent(None)
|
||
|
item = self.graphics_layout.takeAt(0)
|
||
|
self.graphics_layout.removeWidget(self.canvas)
|
||
|
self.canvas = FigureCanvas(fig)
|
||
|
self.toolbar = NavigationToolbar(self.canvas, self.ui.graphicsView)
|
||
|
self.toolbar.setParent(self.canvas)
|
||
|
self.graphics_layout.addWidget(self.canvas)
|
||
|
self.adjustSize()
|
||
|
|
||
|
def choose_datafile(self):
|
||
|
file_dialog = QFileDialog(self)
|
||
|
file_dialog.setFileMode(QFileDialog.ExistingFiles)
|
||
|
if file_dialog.exec():
|
||
|
self.file_paths += file_dialog.selectedFiles()
|
||
|
self.ui.data_file_lineEdit.setText(','.join(self.file_paths))
|
||
|
self.plot_density()
|
||
|
|
||
|
def choose_wellfile(self):
|
||
|
file_dialog = QFileDialog(self)
|
||
|
file_dialog.setFileMode(QFileDialog.ExistingFiles)
|
||
|
if file_dialog.exec():
|
||
|
file_paths = file_dialog.selectedFiles()
|
||
|
self.ui.well_file_lineEdit.setText(','.join(file_paths))
|
||
|
self.plot_density()
|
||
|
|
||
|
def legend_color_chose(self):
|
||
|
col = QColorDialog.getColor()
|
||
|
self.color[self.num] = col.name()
|
||
|
self.num += 1
|
||
|
self.plot_density()
|
||
|
|
||
|
def oil_well_color(self):
|
||
|
col = QColorDialog.getColor()
|
||
|
self.oilwell_color = col.name()
|
||
|
|
||
|
def water_well_color(self):
|
||
|
col = QColorDialog.getColor()
|
||
|
self.waterwell_color = col.name()
|
||
|
|
||
|
def color_bar(self):
|
||
|
self.ui.colorbar_chose.addItem("jet")
|
||
|
self.ui.colorbar_chose.addItem("viridis")
|
||
|
self.ui.colorbar_chose.addItem("coolwarm")
|
||
|
self.ui.colorbar_chose.addItem('plasma')
|
||
|
self.ui.colorbar_chose.addItem("magma")
|
||
|
self.ui.colorbar_chose.addItem("inferno")
|
||
|
|
||
|
def update_colorbar(self):
|
||
|
colorbar_name = self.ui.colorbar_chose.currentText()
|
||
|
self.colorbar = plt.get_cmap(colorbar_name)
|
||
|
self.plot_density()
|
||
|
|
||
|
def clear_data(self):
|
||
|
self.file_paths = []
|
||
|
self.color = self.get_color(100)
|
||
|
self.num = 0
|
||
|
self.ui.data_file_lineEdit.clear()
|
||
|
self.ui.well_file_lineEdit.clear()
|
||
|
self.canvas.figure.clf() # 清除画布上的内容
|
||
|
self.canvas.draw()
|
||
|
|
||
|
def center_scale(self):
|
||
|
if self.chose == 0:
|
||
|
self.chose = 1
|
||
|
else:
|
||
|
self.chose = 0
|
||
|
self.num = 0
|
||
|
|
||
|
def plot_density(self):
|
||
|
fig, ax = self.scene_fig()
|
||
|
data_name = self.ui.data_file_lineEdit.text().split(',') # 文件输入 =================1
|
||
|
level_nums = self.ui.level_chose.value() # 层参数 =================2
|
||
|
gWeight = self.ui.gWeight_chose.value() # 权重输入 =================3
|
||
|
data = CREAT.create()
|
||
|
legend_elements = []
|
||
|
if self.num == len(data_name):
|
||
|
self.num = 0
|
||
|
for i in range(len(data_name)):
|
||
|
data.data_pre(data_name[i])
|
||
|
data.contours_pre(level_nums, gWeight)
|
||
|
|
||
|
"""画出密度等高线"""
|
||
|
f = data.f
|
||
|
x_min, x_max = data.x_range[0], data.x_range[1]
|
||
|
y_min, y_max = data.y_range[0], data.y_range[1]
|
||
|
levels = data.levels
|
||
|
|
||
|
xx, yy = np.mgrid[x_min:x_max:200j, y_min:y_max:200j]
|
||
|
# 填充等高线图中间的区域
|
||
|
|
||
|
if len(data_name) > 1:
|
||
|
color_i = self.color[i] # """ 自动选择图例的颜色""" =================4
|
||
|
level = [levels[0], levels[-1]]
|
||
|
ff = ax.contourf(xx, yy, f, levels=level, colors=color_i, alpha=1, zorder=len(data_name) - i)
|
||
|
# 生成图例
|
||
|
legend_elements.append(Patch(facecolor=color_i, label='第'+f'{i+1}'+'次'))
|
||
|
if i == len(data_name)-1:
|
||
|
ax.legend(handles=legend_elements, loc='upper right', prop={'family': 'SimHei', 'size': 10})
|
||
|
# ax.legend(prop={'family': 'SimHei', 'size': 15})
|
||
|
else:
|
||
|
# colorbars = 'jet' # 输入选择的colorbar =================5
|
||
|
cmap = mpl.colormaps.get_cmap(self.colorbar)
|
||
|
colors = cmap(np.linspace(0, 1, level_nums))
|
||
|
ff = ax.contourf(xx, yy, f, levels=levels, colors=colors[0:level_nums], alpha=0.5,
|
||
|
zorder=len(data_name) - i)
|
||
|
# 生成colorbar
|
||
|
sm = mpl.cm.ScalarMappable(cmap=cmap, norm=mpl.colors.Normalize(vmin=ff.zmin, vmax=ff.zmax))
|
||
|
sm.set_array([])
|
||
|
fig.colorbar(sm, ax=ax)
|
||
|
|
||
|
ax.set_xlabel('X')
|
||
|
ax.set_ylabel('Y')
|
||
|
ax.set_title('Density Distribution')
|
||
|
|
||
|
wells_name = self.ui.well_file_lineEdit.text() # 井文件输入 =================6
|
||
|
if wells_name == '':
|
||
|
self.canvas_adjust(fig)
|
||
|
else:
|
||
|
wells = CREAT.well_to_edge()
|
||
|
wells.wells_name_and_position(wells_name)
|
||
|
wells.welltoedge_distance(data.contours)
|
||
|
|
||
|
"""画井位信息"""
|
||
|
typee = wells.type
|
||
|
points = wells.position
|
||
|
namee = wells.name
|
||
|
min_distance = wells.min_distance
|
||
|
contours_p = wells.welltoedge_points
|
||
|
x_len = ((np.array(points)[:, 0].max()-np.array(points)[:,0].min())//100+2)*100
|
||
|
y_len = ((np.array(points)[:, 1].max()-np.array(points)[:,1].min())//100+2)*100
|
||
|
if self.chose == 1:
|
||
|
max_x = max(np.array([(np.array(points)[:, 0].max()//100+1)*100, (np.array(points)[:, 1].max()//100+1)*100, data.x_range[1], data.y_range[1]]))
|
||
|
min_x = max(np.array([(np.array(points)[:, 0].min()//100-1)*100, (np.array(points)[:, 1].min()//100-1)*100, data.x_range[0], data.y_range[0]]))
|
||
|
max_x = max(max_x, -min_x)
|
||
|
ax.set_xlim([-max_x, max_x])
|
||
|
ax.set_ylim([-max_x, max_x])
|
||
|
x_len = max(x_len, y_len)
|
||
|
y_len = x_len
|
||
|
|
||
|
for i in range(len(points)):
|
||
|
is_inside = False # 标记点是否在等高线内部
|
||
|
# path = Path(contours_p)
|
||
|
# if path.contains_point(points[i]):
|
||
|
if np.linalg.norm(contours_p[i]) >= np.linalg.norm(points[i]):
|
||
|
is_inside = True
|
||
|
if typee[i][0] == 0:
|
||
|
# oil_color = 'black' # 输入油井颜色选择 =================8
|
||
|
ax.scatter(points[i][0], points[i][1], marker='o', edgecolors=self.oilwell_color, facecolors='none', s=70)
|
||
|
ax.scatter(points[i][0], points[i][1], marker='o', edgecolors=self.oilwell_color, facecolors='none', s=40,
|
||
|
linewidths=0.5)
|
||
|
ax.scatter(points[i][0], points[i][1], marker='o', edgecolors=self.oilwell_color, facecolors='none', s=20)
|
||
|
if wells.angle[i] <= 90:
|
||
|
ax.text(points[i][0] - 1/35*x_len, points[i][1] - 1/30*y_len, f'{namee[i][0]}',
|
||
|
fontdict={'size': '8', 'color': 'b'}) # 井名信息
|
||
|
elif wells.angle[i] > 270:
|
||
|
ax.text(points[i][0] + 3/175*x_len, points[i][1] - 1/40*y_len, f'{namee[i][0]}',
|
||
|
fontdict={'size': '8', 'color': 'b'}) # 井名信息
|
||
|
else:
|
||
|
ax.text(points[i][0] - 3/80*x_len, points[i][1] + 3/175*y_len, f'{namee[i][0]}',
|
||
|
fontdict={'size': '8', 'color': 'b'}) # 井名信息
|
||
|
if not is_inside:
|
||
|
# 绘制油井边缘最短距离点的箭头并标出距离
|
||
|
ax.quiver(points[i][0], points[i][1], contours_p[i][0] - points[i][0],
|
||
|
contours_p[i][1] - points[i][1],
|
||
|
angles='xy', scale=1.03,
|
||
|
scale_units='xy', width=0.002, zorder=len(data_name) + 1) # 绘制箭头
|
||
|
if np.linalg.norm(np.array(points[i])-np.array(contours_p[i])) > 50:
|
||
|
ax.text(points[i][0] * 1 / 2 + contours_p[i][0] * 1 / 2 + min_distance[i] / 18,
|
||
|
points[i][1] * 1 / 2 + contours_p[i][1] * 1 / 2 - min_distance[i] / 18,
|
||
|
f'{round(min_distance[i], 2)}m',
|
||
|
fontdict={'size': '8', 'color': 'm'}) # 标出距离
|
||
|
else:
|
||
|
if wells.angle[i] <= 90:
|
||
|
ax.text(points[i][0]-3/70*x_len, points[i][1]+1/40*y_len, f'{round(min_distance[i], 2)}m',
|
||
|
fontdict={'size': '8', 'color': 'm'}) # 标出距离
|
||
|
elif wells.angle[i] > 270:
|
||
|
ax.text(points[i][0] - 1/35*x_len, points[i][1] + 1/30*y_len, f'{round(min_distance[i], 2)}m',
|
||
|
fontdict={'size': '8', 'color': 'm'}) # 标出距离
|
||
|
else:
|
||
|
ax.text(points[i][0] + 3/140*x_len, points[i][1] - 1/40*y_len, f'{round(min_distance[i], 2)}m',
|
||
|
fontdict={'size': '8', 'color': 'm'}) # 标出距离
|
||
|
else:
|
||
|
# water_color = 'black' # 水井颜色 =================9
|
||
|
ax.scatter(points[i][0], points[i][1], marker='o', edgecolors=self.waterwell_color, facecolors=self.waterwell_color, s=70, zorder=len(data_name)+1)
|
||
|
ax.text(points[i][0] + 15, points[i][1] - 15, f'{namee[i][0]}',
|
||
|
fontdict={'size': '8', 'color': 'b'}, zorder=len(data_name) + 2) # 井名信息
|
||
|
continue
|
||
|
self.canvas_adjust(fig)
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
app = QApplication([])
|
||
|
stats = MainWindow()
|
||
|
stats.ui.show()
|
||
|
app.exec()
|