Python的地形三维可视化——简介Matplotlib和gdal

虾神前段时间因为工作关系,去灯塔国享受了一把时差,所以有两周没有更新博客了,幸好有撸文小能手吴道长帮忙,写了这样一篇文章,所以先应急发出来。


题外话:长期不更新还不掉的粉,才是铁杆粉


下面是正文,本文版权属于python代码界后起之秀吴道长所有。


————————我是分割线————————


撸这文,是为了向大虾致敬。大虾曾今用R语言对DEM数据进行三维可视化构建。链接如下:

http://blog.csdn.net/allenlu2008/article/details/49874111

我是以Python开门的,我还是觉得Python也可以进行地形三维可视化,当然这里需要借助第三方库,so,我就来介绍:Python一个很重要可视化插件,Matplotlib。
Matplotlib 是Python最著名的绘图库,它提供了一整套友好的命令,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。你会发现Matplotlib和matlab相似,但是你知道matlab强大是很强大,但是安装包就有7G,一下就让我失去玩弄他的兴趣。
Matplotlib的二维图形非常成熟,可以做各种各样的报表,比如:

好吧,额,....... Matplotlib当然也可以做3维数据。首先准备了一份样例,珠穆朗姆峰周围地势的dem数据,我在arcsense进行拉伸显示,初步看看效果:


讲这份数据,输入编写好的相关路径,然后经过简单的三维渲染:

Matplotlib只是一个可视化包,不能直接识别栅格数据,所以这边还用到另外一个包---gdal,开源栅格空间数据转换库,他的本体竟然还是c++,也开放了一个Python框架,这算是向Python投诚嘛?我们有必要重申一下:

好吧,开源一下用Matplotlib和gdal包进行地形三维可视化的小脚本:


# -*- coding: gbk -*-
from mpl_toolkits.mplot3d import Axes3D
from Matplotlib import cbook
from Matplotlib import cm
from Matplotlib.colors import LightSource
import Matplotlib.pyplot as plt
import numpy as np
from osgeo import gdal
gdal.AllRegister()


filePath = u"E:\桌面\dem实验/Himalaya.tif"  #输入你的dem数据

dataset = gdal.Open(filePath)
adfGeoTransform = dataset.GetGeoTransform()
band = dataset.GetRasterBand(1)   #用gdal去读写你的数据,当然dem只有一个波段

nrows  =  dataset.RasterXSize  
ncols   =  dataset.RasterYSize   #这两个行就是读取数据的行列数


Xmin = adfGeoTransform[0]  #你的数据的平面四至
Ymin = adfGeoTransform[3]
Xmax = adfGeoTransform[0] + nrows * adfGeoTransform[1] + ncols * adfGeoTransform[2]
Ymax = adfGeoTransform[3] + nrows * adfGeoTransform[4] + ncols * adfGeoTransform[5]

x = np.linspace(Xmin,Xmax, ncols)
y = np.linspace(Ymin,Ymax, nrows)
X,Y = np.meshgrid(x, y)
Z = band.ReadAsArray(0, 0,nrows, ncols) #这一段就是讲数据的x,y,z化作numpy矩阵

region = np.s_[10:400,10:400]
X, Y, Z = X[region], Y[region],Z[region]

fig, ax = plt.subplots(subplot_kw=dict(projection='3d'), figsize=(12,10))
ls = LightSource(270, 20)   #设置你可视化数据的色带
rgb = ls.shade(Z, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft')
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=rgb,
                        linewidth=0, antialiased=False, shade=False)

plt.show()  #最后渲染出你好看的三维图吧




最后是虾神的话:GDAL在python里面的安装,属于灰常纠结的事情,运气好(人品好)可能一下就成功,运气不好,可能死活就装不上……如果遇上死活装不上的,可以考虑用MinGW自己进行编译。


如果不想用gdal来实现以上效果,可以考虑用arcpy的RasterToNumpy来把tif文件读成矩阵,也可以实现。


具体还有啥问题的,可以咨询吴道长,吴道长的联系方式,可以给虾神发邮件索取。
<think>好的,用户想用Python绘制三维地形图,使用matplotlib或plotly。我需要根据提供的引用资料来组织回答。首先,我得确定用户的需求,可能需要分步骤说明两种库的实现方法。 先看引用里的信息。引用3提到使用Matplotlibgdal进行地形三维可视化,引用4给出了plot_trisurf的示例代码。引用12是Matplotlib的基础教程3D平面绘制。用户可能对地形数据来源不太清楚,所以需要包括数据准备部分,比如使用GDAL读取DEM数据。 我应该先介绍Matplotlib的方法,因为引用中有更多相关资料。步骤可能包括:导入库、加载数据、创建网格、绘制曲面、添加标签颜色条。然后,再转到Plotly,因为它是交互式的,可能更直观。需要提到plotly.expressSurface图的使用。 需要注意代码示例的正确性,比如使用numpy生成示例数据,或者从文件读取真实数据。同时,要提醒安装必要的库,比如matplotlib、plotly、gdal等。可能还需要提到优化方法,如颜色映射视角调整,以及处理大规模数据时的性能问题。 用户的问题可能还涉及如何自定义可视化效果,比如颜色透明度,所以应该包含这些调整的代码示例。最后,生成相关问题,帮助用户深入,比如性能优化、数据导入、交互式功能比较等。 检查是否有遗漏点,比如是否需要解释三维地形图的原理,但用户可能更关注实现步骤,所以保持实用为主。确保所有数学公式或代码块格式正确,使用$...$或$$...$$,但这里主要是代码块,所以用三个反引号包裹。最后验证引用标记是否正确对应到参考资料。</think>以下是如何使用PythonMatplotlibPlotly实现三维地形图的分步指南: ### 一、Matplotlib实现方法 1. **数据准备** - 推荐使用DEM(数字高程模型)数据,可通过GDAL库读取GeoTIFF文件: ```python from osgeo import gdal dataset = gdal.Open('terrain.tif') elevation = dataset.ReadAsArray() ``` - 或生成模拟数据: ```python import numpy as np x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x, y) Z = np.sin(np.sqrt(X**2 + Y**2)) # 生成波浪状地形 ``` 2. **基础绘图** ```python import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') surf = ax.plot_surface(X, Y, Z, cmap='terrain', linewidth=0, antialiased=True) fig.colorbar(surf, shrink=0.5, aspect=5) ax.set_xlabel('经度') ax.set_ylabel('纬度') ax.set_zlabel('高程') plt.show() ``` 3. **高级优化** ```python ax.view_init(elev=45, azim=120) # 调整视角 surf.set_clim(vmin=Z.min(), vmax=Z.max()*0.8) # 设置颜色范围 ax.dist = 10 # 调整视距 ``` ### 二、Plotly实现方法(交互式可视化) ```python import plotly.graph_objects as go fig = go.Figure(data=[go.Surface( z=Z, colorscale='Viridis', contours={ "z": {"show": True, "usecolormap": True} } )]) fig.update_layout( title='三维地形图', scene=dict( xaxis_title='经度', yaxis_title='纬度', zaxis_title='高程', camera_eye=dict(x=1.5, y=1.5, z=0.8) ), autosize=False, width=1000, height=800 ) fig.show() ``` ### 三、关键参数说明 1. **颜色映射** - Matplotlib: `cmap='terrain'`, `cmap='gist_earth'` - Plotly: `colorscale='Viridis'`, `colorscale='Plasma'` 2. **性能优化** ```python # 降低采样率(适用于大数据) downsampled = Z[::2, ::2] # 使用三角化网格 from scipy.spatial import Delaunay tri = Delaunay(np.vstack([X.ravel(), Y.ravel()]).T) ax.plot_trisurf(X.ravel(), Y.ravel(), Z.ravel(), triangles=tri.simplices, cmap='terrain') ``` ### 四、真实数据应用 使用SRTM高程数据(需转换为CSV或numpy格式): ```python # 假设已有高程矩阵Z坐标矩阵X,Y fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_surface(X, Y, Z, rstride=5, cstride=5, # 采样间隔 cmap=plt.cm.terrain, alpha=0.8) # 设置透明度 ax.contour(X, Y, Z, 15, zdir='z', offset=-0.5) # 添加等高线 ``` [^1]: 使用Matplotlib进行3D可视化时需要正确设置投影参数 [^2]: Plotly的交互式特性更适合动态探索地形特征 [^3]: GDAL库支持多种地理空间数据格式的读取
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虾神说D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值