为了实现不同数据的可视化,最近研究了python环境下的可视化方案,为后续的流体运动仿真模拟做好储备,由于python处理数据的便利性,导致目前很多后端处理或者可视化成图操作都在python中实现,比如前端是vue,加上简单的交互操作,后端搭建webserver,可采用java或者python来搭建,并利用python在后端处理数据,形成可视化图件等;本文主要在python3.10环境下,利用 matplotlib.pyplot、scipy.interpolate、numpy、pandas实现数据的处理,网格数据的生成,各自平面图和三维图形的绘制,并加入自定义颜色栏。在绘图开始之前,需要准备数据,一般包括读取和准备数据,以及简单的数据处理过滤等,后续会在此基础上进行绘图操作或继续进行数据处理及可视化等。
准备数据阶段
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 准备数据 读取数据 # 0.读写实际数据生成三维曲面,数据格式为x y z filename = r 'D:projectPythonProjectECLdatageochemical-data2018_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文件内容
读取后的数据样式,xyz的shape形状,都是相同长度的一维数组,即(12766,) (12766,) (12766,).
一、利用xyz绘制三维曲面
1 2 3 4 5 | 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() |
利用三角网格绘制的三维曲面图和三维散点图
二、利用xyz生成网格后绘制三维曲面
1 2 3 4 5 6 7 8 9 10 | 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() |
三维曲面图、散点图和等值线图
三、利用xyz实现三维等值线绘制,降雨量三维等值线图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | filename = r 'D:projectPythonProjectECLdatageochemical-data.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() |
效果图和数据格式
四、绘制二维等值线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # 绘制二维等值线 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() |
两种二维等值线图
五、绘制矢量流线图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # 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 |
示例效果图和实际数据案例图
附录
1.scipy.interpolate.griddata参数说明
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()参数说明
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:表示流线的最大长度。
以上就是利用python绘制二三维曲面和矢量流线图的详细内容,更多关于python二三维曲面和矢量流线图的资料请关注IT俱乐部其它相关文章!