Use python to draw 2D and 3D surfaces and vector streamlines

       In order to realize the visualization of different data, the visualization scheme in the python environment has been studied recently to prepare for the subsequent fluid motion simulation simulation. Due to the convenience of python to process data, many back-end processing or visualization operations are currently performed in python. For example, the front-end is vue, plus simple interactive operations, and the back-end builds a webserver, which can be built with java or python, and uses python to process data at the back-end to form visual maps, etc.; this article is mainly in the python3.10 environment Next, use matplotlib.pyplot, scipy.interpolate, numpy, and pandas to realize data processing, grid data generation, and drawing of respective planar and three-dimensional graphics, and add a custom color bar. Before drawing starts, data needs to be prepared, generally including reading and preparing data, as well as simple data processing and filtering, etc., and subsequent drawing operations or continued data processing and visualization will be performed on this basis.

data preparation stage

# 准备数据 读取数据
# 0.读写实际数据生成三维曲面,数据格式为x y z
filename=r'D:\project\PythonProject\ECL\data\geochemical-data\2018_T28.txt'
dataTop = pd.read_csv(filename, sep='\t', header=None, names=['x', 'y', 'z'])
# 去掉无效数据,一般为-99999.0000
data = dataTop[dataTop['z'] != -99999.0000]
x = data.iloc[:, 0]
y = data.iloc[:, 1]
z = data.iloc[:, 2]*(-1) #深度值是负数,要取反。
xi = np.linspace(min(x), max(x))
yi = np.linspace(min(y), max(y))
xi, yi = np.meshgrid(xi, yi) # 将一维数据处理为二维的网格数据
zi = griddata(data.iloc[:,0:2], z, (xi, yi), method='cubic') # 用法详见附录1

2018_T28.txt file content

The read data style and the shape of xyz are all one-dimensional arrays of the same length, namely (12766,) (12766,) (12766,).

1. Use xyz to draw a three-dimensional surface

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(x, y, z, color='white', edgecolors='grey', alpha=0.5) #绘制三角网格组成的三维曲面
ax.scatter(x, y, z, c='red')  # 绘制三维散点图
plt.show()

 3D surface plot and 3D scatter plot using triangular mesh

2. Use xyz to generate a grid and draw a three-dimensional surface

fig = plt.figure()
# ax = plt.axes(projection='3d')
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xi, yi, zi, cmap='BuPu', linewidth=0, antialiased=True)  #绘制三维曲面
# surf = ax.scatter(xi, yi, zi, cmap='BuPu', linewidth=0, antialiased=True)     #绘制三维散点图
# surf = ax.contourf(xi, yi, zi, zdim='z',offset=0.3, cmap='BuPu')   #等高线面图(contourf)或等高线图(contour),要设置offset,为Z的最小值,
fig.colorbar(surf)
ax.set_title('三维图')
ax.set_zlim3d(np.min(z), np.max(z))
plt.show()

3D surface, scatter, and contour plots

3. Using xyz to realize three-dimensional contour drawing, three-dimensional contour map of rainfall

filename = r'D:\project\PythonProject\ECL\data\geochemical-data\0.txt'  # 数据文件地址,附件1
df = pd.read_csv(filename, sep="\t")  # 读取文件
df1 = df["1"]  # 读取第一列数据
df2 = df['2']  # 读取第二列数据
df3 = df['3']  # 读取第三列数据
odf1 = np.linspace(100, 1900, 50)  # 设置网格经度
odf2 = np.linspace(10, 600, 50)  # 设置网格纬度
odf1, odf2 = np.meshgrid(odf1, odf2)  # 网格化,生成网络,生成网格形状是第一个维度对应odf1,第二个维度对应odf2
func = Rbf(df1, df2,df3, function='linear')  # 定义插值函数plt.cm.hot
odf3_new = func(odf1, odf2)  # 获得插值后的网格累计降水量
fig = plt.figure(figsize=(12, 7))
ax1 = plt.axes(projection='3d')  # 创建三维坐标轴
ax1.plot_surface(odf1, odf2, odf3_new,alpha=0.3,cmap='rainbow') #绘制三维曲面,alpha-控制透明度,cmap-控制颜色
# 绘制z方向投影填充图,等高线面图,投到x-y平面,offset为z最小值。
cs=plt.contourf(odf1, odf2, odf3_new,zdir='z',offset=0,
             levels=np.arange(odf3_new.min(), odf3_new.max(), (odf3_new.max() - odf3_new.min()) / 10), cmap='GnBu',
             extend='both')  # 画图
# 绘制等高线图
line = plt.contour(odf1, odf2, odf3_new,zdir='z',offset=0,cmap="rainbow",levels=np.arange(odf3_new.min(), odf3_new.max(), (odf3_new.max() - odf3_new.min()) / 10))
plt.clabel(line, inline=True, fontsize=12)
ax1.set_title('降雨量三维等值线图')
plt.colorbar(cs)
plt.show()

Renderings and Data Formats

4. Draw two-dimensional contour lines

# 绘制二维等值线
levels = np.linspace(np.min(z), np.max(z), 50)
fig, ax = plt.subplots(figsize=(8, 6))

# # 1.设置颜色条  第一种方式
# print(cm.colors.cnames)
# 默认颜色标如 jet,coolwarm,gnuplot2_r,RdBu_r,PuBuGn_r,ocean_r,输入的颜色名称错误时,会自动输出色标的列表
cmap = cm.get_cmap('seismic_r')
# cmap = cm.get_cmap('jet', 10)  # 将色条分成10截
norm = cm.colors.Normalize(vmin=np.min(z), vmax=np.max(z))  # 设置色条表示的数值范围
im1 = cm.ScalarMappable(norm=norm, cmap=cmap)               # 设置映射很重要
# # 绘制颜色条(left, bottom, width, height)--表示figure的百分比,从figure 从横向92%,纵向10%的位置开始绘制, 宽是figure的3%,高是figure的78%,
ax9 = fig.add_axes([0.92, 0.1, 0.03, 0.78])
cb = plt.colorbar(im1, cax=ax9, orientation='vertical', extend='neither') #纵向绘制,两端无箭头
# ticks与norm对应
# # cb = plt.colorbar(im1, cax=ax9, orientation='horizontal', extend='max', ticks=np.linspace(1900,2600, 51))
# cs = ax.contour(xi, yi, zi, levels=levels, cmap=cmap)         # 不存在颜色间隔分段,并指定颜色条
# cs = ax.contour(xi, yi, zi, levels=levels,cmap='coolwarm')  # 存在颜色间隔分段
cs = ax.contourf(xi, yi, zi, levels=levels,cmap='jet',extend='neither') # 等值线填充
ax.clabel(cs, inline=True, fontsize=6)
ax.set_title('等高线图')
plt.show()

# # 2.设置颜色条 第二种方式
# cs = ax.contourf(xi, yi, zi, levels=levels, cmap='jet', extend='neither')  # 等值线填充,存在颜色间隔分段
# # ax.clabel(cs, inline=True, fontsize=6)
# ax.set_title('等高线图')
# plt.colorbar(cs)
# plt.show()

Two 2D Contour Maps

5. Draw a vector streamline diagram

# 1.矢量场流线图 样例
# 0:5表示数组中数值所在的区间。100j表示划分的密度,值越大,图片越清晰
Y1, X1 = np.mgrid[-5:5:1000j, -5:5:10j]
# (X,Y)是一维numpy数组的等距网格,(U,V)参数匹配的是(X,Y)速率的二维numpy数组
# U,V矩阵在维度上的行数必须等于Y的长度,列的数量必须匹配X的长度
U = -1 - X1 ** 2 + Y1
V = 1 + X1 - Y1 ** 2
# 可视化矢量场
# 矢量场中的种子点坐标
seed_points = np.array([[-2, -1, 0, 1, 2, -1], [-2, -1, 0, 1, 2, 2]]) # 种子点
# cs=plt.streamplot(X1, Y1, U, V,density=[0.5,1],color=U,cmap="autumn",linewidth=1,start_points=seed_points.T)
cs = plt.streamplot(X1, Y1, U, V, color=U, cmap="Accent", linewidth=1)
# plt.plot(seed_points[0], seed_points[1], "+", color="g") # 绘制折线图,使用marker属性标记
plt.colorbar()
plt.show()

# 2.用实际数据进行绘制,UV如何计算得到,要根据不同的目的进行计算。
U,V=vectorComputeUV(xi,yi,zi)
cs = plt.streamplot(xi, yi, U, V, color=U, cmap="Accent", linewidth=1)
# cs = plt.quiver(xi, yi, U, V)
plt.colorbar()
plt.show()

# 计算矢量场的速度矢量
def vectorComputeUV(xi,yi,zi):
    # U = np.log10((xi/10000)) - zi/1000
    # V = 1 + np.log10(yi/100000) - (zi/1000) ** 3
    U = -1 - (xi/10000) ** 2 + (yi/100000)
    V = 1 + (xi/10000)  - (yi/100000) ** 2
    return U,V

Example renderings and actual data case diagrams

appendix

1. scipy.interpolate.griddata parameter description

scipy.interpolate.griddata的参数说明如下
插入非结构化D-D 数据
    points: 具有形状 (n, D) 的浮点数的二维 ndarray,或具有形状 (n,) 的一维 ndarray 的长度 D 元组。
    数据点坐标。
    values: 浮点数或复数的ndarray,形状(n,)
    数据值。
    xi: 具有形状 (m, D) 或长度为 D 的 ndarray 元组的二维 ndarray 可广播到相同形状。
    插入数据的点。
    method: {‘linear’, ‘nearest’, ‘cubic’},可选
    插值方法。之一
    fill_value: 浮点数,可选
    用于填充输入点凸包之外的请求点的值。如果未提供,则默认值为 nan 。此选项对‘nearest’ 方法无效。
    rescale: 布尔型,可选
    在执行插值之前将点重新缩放到单位立方体。如果某些输入维度具有不可比较的单位并且相差许多数量级,这将很有用。
返回
    ndarray
    插值数组。

2. streamplot() parameter description

matplotlib.pyplot.streamplot()参数说明如下:
  x,y:表示间距均匀的网格数据。
  u,v:表示(x, y)速率的二维数组。
  density:表示流线的密度,默认为1。
   color:表示流线颜色。一般设置为U
   cmap:表示线条颜色系,一般有'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens'
  linewidth:表示流线的宽度。
  arrowsize:表示箭头的大小。
  arrowstyle:表示箭头的类型。
  minlength:表示流线的最小长度。
  maxlength:表示流线的最大长度。

Guess you like

Origin blog.csdn.net/hhue2007/article/details/131613246