python 科学计算三维可视化笔记(第四周 进阶实战)


内容来自中国大学MOOC,北京理工大学,python数据分析与展示课程,侵删。
如有错误,烦请指出。


python 科学计算三维可视化笔记 第四周 进阶实战

一、实例1:Dragon 绘制

  • 读取 tar 压缩文件
  • 读取 .ply 数据文件
  • 渲染 dragon ply文件,绘制数据的 surface
  • 显示可交互的结果
  • 删除解压的文件夹
'''实例1:dragon'''
from mayavi import mlab
from os.path import join
import tarfile
 
# 读取tar压缩文件
dragon_tar_file = tarfile.open('dragon.tar.gz')
try:
    os.mkdir('dragon_data')
except:
    pass
dragon_tar_file.extractall('dragon_data')
dragon_tar_file.close()

# 读取数据文件
dragon_ply_file = join('dragon_data', 'dragon_recon', 'dragon_vrip.ply')
 
# 渲染dragon ply文件
mlab.pipeline.surface(mlab.pipeline.open(dragon_ply_file))

# 显示可交互的结果
mlab.show()
 
# 删除解压的文件夹
import shutil
shutil.rmtree('dragon_data')

1.1 - dragon

二、实例2:Canyon 地形可视化

  • 读取压缩文件
  • 处理地形数据
  • 渲染地形数据
  • 清空内存
  • 创建交互式的可视化窗口
  • 显示可交互的结果
'''实例2:Canyon 地形可视化'''
import zipfile
import numpy as np
from mayavi import mlab
 
# 读取压缩文件
hgt = zipfile.ZipFile('N36W113.hgt.zip').read('N36W113.hgt')

# 处理地形数据
data = np.fromstring(hgt,'>i2')
data.shape = (3601, 3601)
data = data.astype(np.float32)
data = data[:1000, 900:1900]
data[data == -32768] = data[data > 0].min()
 
# 渲染地形数据
mlab.figure(size=(400, 320), bgcolor=(0.16, 0.28, 0.46))
mlab.surf(data, colormap='gist_earth', warp_scale=0.2,
            vmin=1200, vmax=1610)
 
# 清空内存
del data

# 创建交互式的可视化窗口
mlab.view(-5.9, 83, 570, [5.3, 20, 238])

# 显示可交互的结果
mlab.show()

2 - canyon

三、实例3:Earth Graph

1. 数据处理
  • 构造城市互联数据 connec_data
  • 构造城市坐标数据 cities_data
  • 建立城市互联列表 connec
  • 建立城市索引 cities
  • 建立城市:经纬度索引 cities_coord
  • 建立经纬度列表 coords
2. 坐标转换

将经纬度的位置转换为三维坐标,lng 为经度,lat 为纬度:

  • x = cos ⁡ ( l n g ) ∗ cos ⁡ ( l a t ) x=\cos(lng) * \cos(lat) x=cos(lng)cos(lat)
  • y = cos ⁡ ( l n g ) ∗ sin ⁡ ( l a t ) y=\cos(lng) * \sin(lat) y=cos(lng)sin(lat)
  • z = sin ⁡ ( l n g ) z=\sin(lng) z=sin(lng)
3. 绘制图像
  • 建立窗口
  • 绘制地球
  • 绘制城市点位
  • 显示城市互联
  • 显示城市名字
  • 绘制大洲边界
  • 绘制赤道、南北回归线、南北极圈
  • 显示可交互窗口
4. 代码
'''实例3:Earth Graph'''

import csv
import numpy as np
from mayavi import mlab
from mayavi.sources.builtin_surface import BuiltinSurface

########### 数据处理 ###########
# 城市互联数据
connec_data = """
Beijing,Shanghai
Bombay,Atlanta
Bombay,Newark
Bombay,New York
Chicago,Delhi
Doha,Houston
Dubai,Houston
Dubai,Los Angeles
Dubai,Sao Paulo
Dubai,San Francisco
Johannesburg,Atlanta
Los Angeles,Sydney
New York,Hong Kong
Newark,Hong Kong
Shanghai,Hong Kong
Toronto,Hong Kong
Vancouver,Hong Kong
"""

# 城市坐标数据,城市city,经度longtitude,纬度latitude
cities_data = """
Atlanta,       -84.42,  33.76
Beijing,       116.23,  39.54
Bombay,        72.82,   18.96
Chicago,       -87.68,  41.84
Delhi,         77.21,   28.67
Doha,          51.53,   25.29
Dubai,         55.33,   25.27
Hong Kong,     114.19,  22.38
Houston,       -95.39,  29.77
Johannesburg,  28.04,   -26.19
Los Angeles,   -118.41, 34.11
Newark,        -82.43,  40.04
New York,      -73.94,  40.67
San Francisco, -122.45, 37.77
Sao Paulo,     -46.63,  -23.53
Shanghai,      121.52,  30.91
Sydney,        151.21,  -33.87
Toronto,       -79.38,  43.65
Vancouver,     -123.13, 49.28
"""

# 城市互联列表connec
connec = list()
for city1, city2 in list(csv.reader(routes_data.split('\n')))[1:-1]:
    connec.append((cities[city1], cities[city2]))
#print('connec:', connec)
connec = np.array(connec)
#print('connec:', connec)

# 城市索引cities,城市:经纬度索引cities_coord,经纬度列表coords
cities = dict()
cities_coord = dict()
coords = list()
for line in list(csv.reader(cities_data.split('\n')))[1:-1]:
    name, lng, lat = line
    cities[name] = len(coords)    
    cities_coord[name] = (float(lng), float(lat))
    coords.append((float(lng), float(lat)))
#print('cities: ', cities)
#print('cities_coord: ', cities_coord)
#print('coords: ', coords)
coords = np.array(coords)
#print('coords: ', coords)


################# 坐标转换 #################
# 将经纬度的位置转换为三维坐标
lat, lng = coords.T * np.pi / 180
x = np.cos(lng) * np.cos(lat)
y = np.cos(lng) * np.sin(lat)
z = np.sin(lng)


################# 绘制图像 #################
# 建立窗口,背景颜色0.48,前景颜色0,0,0为黑色
mlab.figure(bgcolor=(0.48,0.48,0.48), fgcolor=(0,0,0), size=(400,400))
#mlab.figure(1, bgcolor=(0.48, 0.48, 0.48), fgcolor=(0,0,0),size=(400, 400))

# 绘制半透明球体表示地球
sphere = mlab.points3d(0, 0, 0, 
                       scale_factor=2,
                       color=(0.67,0.77,0.93),
                       resolution=50,
                       opacity=0.7,
                       name='Earth')
# 调整镜面反射参数
sphere.actor.property.specular = 0.45
sphere.actor.property.specular_power = 5
# 设置背面剔除,以更好的显示透明效果
sphere.actor.property.backface_culling = True


# 绘制城市点位
points = mlab.points3d(x, y, z, 
                       scale_mode='none',
                       scale_factor=0.03,
                       color=(0,0,1))
# 显示城市互联
points.mlab_source.dataset.lines = connec
points.mlab_source.reset()
mlab.pipeline.surface(points, color=(1,1,1),
                      representation='wireframe',
                      line_width=4,
                      name='Connections')
# 显示城市名字
for city, index in cities.items():
    label = mlab.text(x[index], y[index], city, z=z[index],
                      width=0.016*len(city), name=city)
    label.property.shadow = True


# 绘制大洲边界
continents_src = BuiltinSurface(source='earth', name='Continents')
# 设置LOD为2
continents_src.data_source.on_ratio = 2
continents = mlab.pipeline.surface(continents_src, color=(0,0,0))

# 构造经度数组,从0到360(2pi)
theta = np.linspace(0, 2*np.pi, 100)
# 绘制赤道线0,南北回归线23.5,南北极圈66.5
for angle in (-23.5*np.pi/180, -66.5*np.pi/180, 0, 23.5*np.pi/180, 66.5*np.pi/180):
    x = np.cos(theta) * np.cos(angle)
    y = np.sin(theta) * np.cos(angle)
    z = np.ones_like(theta) * np.sin(angle)
    mlab.plot3d(x, y, z, 
                color=(1, 1, 1),
                opacity=0.2, tube_radius=None)

# 显示可交互窗口
mlab.view(100, 60, 4, [-0.05, 0, 0])
mlab.show()
5. 结果

结果如下,只有大概的大洲轮廓,一些岛屿好像绘制不出来:
3 - 地球

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值