为了实现地层数据的变化趋势的可视化模拟,最近研究了python环境下的可视化方案,为后续的流体运动的仿真模拟做好储备,主要采用matplotlib中的quiver函数,实现二维等值线数据的随深度或者地层数据的变化趋势绘制。
一、运行环境:python3.10环境,利用 matplotlib.pyplot、scipy.interpolate、numpy、pandas实现数据的处理,网格数据的生成,矩阵数据的合并等。
二、数据准备:数据处理和数据准备详见上一篇文章,数据格式和数据读取、数据处理方法类似。
三、二维向量图绘制
典型二维向量场箭头图的绘制
# 1.二维向量风场 典型示例
X = np.arange(-15, 15, 1)
Y = np.arange(-10, 10, 1)
U, V = vectorComputeUV0(X, Y)
font = {'family': 'serif',
'weight': 'normal',
'size': 10,
}
C = np.cos(U)
## 1.1绘制风场风速
fig, ax1 = plt.subplots()
quiver1 = ax1.quiver(X, Y, U, V, C, # X,Y,U,V 确定位置和对应的风速
width=0.003, # 箭杆箭身宽度
scale=100, # 箭杆长度,参数scale越小箭头越长
)
# 1.2绘制方向标识,画出风场、箭头箭轴后,需要说明:箭轴长度与风速的对应关系,详见下面quiverkey
# 风有U\V两个方向,调用quiverkey可以生成横向参考箭头 + label。
ax1.quiverkey(quiver1, # 传入quiver句柄
X=0.09, Y=0.051, # 确定 label 所在位置,都限制在[0,1]之间
U=5, # 参考箭头长度 表示风速为5m/s。
angle=0, # 参考箭头摆放角度。默认为0,即水平摆放
label='v:5m/s', # 箭头的补充:label的内容 +
labelpos='S', # label在参考箭头的哪个方向; S表示南边
color='b', labelcolor='b', # 箭头颜色 + label的颜色
fontproperties=font, # label 的字体设置:大小,样式,weight
)
# 风有U\V两个方向,调用quiverkey可以生成纵向参考箭头 + label
ax1.quiverkey(quiver1, X=0.07, Y=0.071,
U=5,
angle=90, # 参考箭头摆放角度,90即垂直摆放
label='w:5cm/s', # label内容
labelpos='N', # label在参考箭头的北边
color='r', # 箭头颜色
labelcolor='r', # label颜色
fontproperties=font)
plt.show()
效果图
利用实际地层数据绘制
# 数据准备详见第二部分内容。
xi = np.linspace(min(xs), max(xs))
yi = np.linspace(min(ys), max(ys))
xi, yi = np.meshgrid(xi, yi) # 网格化处理
# # 第一个参数:二维数组数据;第二个参数:要生成的维度数据实际散点值;第三个参数:要生成的目标点网格;第四个参数:生成方法;返回值:生成的全部网格对应的Z值数据
zi = griddata(data.iloc[:, 0:2], zs, (xi, yi), method='cubic') #method : {'linear', 'nearest', 'cubic'}
xyz = np.c_[xi, yi, zi] #连接矩阵,行数不变,列数增加。
# 2.用实际盆模数据绘制,UV如何计算得到,详见vectorComputeUV2
# U,V=vectorComputeUV(xs,ys,zs)
threshold = 10 # 阈值,绝对值小于阈值的数据都不显示。
# U = vectorComputeUV3(zs,50)
# cs = plt.quiver(xs, ys, U,U)
U,V = vectorComputeUV2(xyz,threshold)
# cs = plt.quiver(xi, yi, U[:, 0:50], V[:, 0:50])
# cs = plt.quiver(xi, yi, U[:, 50:100], V[:, 50:100])
cs = plt.quiver(xi, yi, U[:, 100:150], V[:, 100:150])
plt.show()
效果图
计算UV方法如下,后续不断完善
# 计算矢量场的速度矢量
def vectorComputeUV0(X,Y):
U, V = np.meshgrid(X, Y)
return U,V
# 计算矢量场的速度矢量,xyz为矢量矩阵,threshold为阈值
def vectorComputeUV2(xyz,threshold):
U, V = np.gradient(xyz) #计算变化趋势,梯度
U=np.where(np.abs(U)<=threshold,0,U) #过滤阈值,U方向
V = np.where(np.abs(V) <= threshold, 0, V) #过滤阈值,V方向
return U,V
# 计算矢量场的速度矢量,zi为输入的一维向量,threshold为阈值
def vectorComputeUV3(zi,threshold):
U = np.gradient(zi,edge_order=1) #计算变化趋势,梯度
U = np.where(np.abs(U) <= threshold, 0, U) #过滤阈值,U方向
return U
quiver([X, Y], U, V, [C], **kw)参数说明
quiver([X, Y], U, V, [C], **kw)参数说明如下:
X, Y 定义了箭头的位置.
U, V 定义了箭头的方向.
C 作为可选参数用来设置颜色.
angles:可选参数,用于指定箭头和x轴之间的角度,以度为单位,默认为UV坐标系下的45度。
scale:可选参数,指定箭头的大小,以矢量长度的一定系数来标识,默认为1.0。
scale_units:可选参数,指定箭头大小的单位,可选值为x、y、xy,默认为xy。
width:可选参数,用于指定箭头的宽度,默认为0.005。
headwidth:可选参数,用于指定箭头的宽度,默认为3倍宽度。
headlength:可选参数,用于指定箭头的长度,默认为4倍宽度。
minshaft:可选参数,用于设定箭头最小长度的比例,这是一个实数,取值在0到1之间。