发布: 更新时间:2024-05-21 16:02:34
等高线在日常生活中是一种常见的地形表示方法,而等高面则是在三维空间中表示“高度一致”的曲面。在二维平面上,“高度”实际上是第三个维度的值,而在三维曲面中,“高度”可以理解为密度,即“高度”越高,“密度”越大。
在Python中,可以使用Matplotlib库绘制等高线。以下是Matplotlib官方示例:
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('_mpl-gallery-nogrid')
# 生成数据
X, Y = np.meshgrid(np.linspace(-3, 3, 256), np.linspace(-3, 3, 256))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)
levels = np.linspace(np.min(Z), np.max(Z), 7)
# 绘图
fig, ax = plt.subplots()
ax.contour(X, Y, Z, levels=levels)
plt.show()
输出图像如下:
此外,还可以使用Matplotlib绘制三维空间的断层扫描等高线,代码如下:
# 在z3维度做断层扫描
def plot3d(distribution, z1, z2, z3, z_level=[0, 5, 10, 15, 20, 25], levels=np.arange(0, 500, 50)):
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
idZ = np.array(z_level, np.int32)
for idx in idZ:
Z = z3[idx]
g = ax.contourf(
z1, z2, distribution[:, :, idx],
zdir='z', offset=z3[idx], levels=levels
)
fig.colorbar(g, ax=ax)
gap = (z3[idZ[-1]]-z3[idZ[0]])/10
ax.set_zlim(z3[idZ[0]]-gap,z3[idZ[-1]]+gap)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
然而,由于绘制出的图像效果一般,并且速度较慢,因此对于这类问题,推荐使用Plotly库来绘制等高面。
以下是绘制等高面的代码示例,需要准备数据,数据维度为:
z1->(m,),z2->(n,),z3->(p,),distribution->(m,n,p)
。代码如下:
def iso_surface(distribution, z1, z2, z3, show=True, save_file=None, colorbar_min=0., colorbar_max=500.,
opacity=0.4, surface_number=3):
import os
try:
import plotly.graph_objects as go
import plotly.offline as offline
except ImportError:
os.system('python3 -m pip install --upgrade plotly')
import plotly.graph_objects as go
import plotly.offline as offline
x, y, z = np.meshgrid(z1, z2, z3)
distribution = distribution.reshape(-1)
fig= go.Figure(data=go.Isosurface(
x=x.reshape(-1),
y=y.reshape(-1),
z=z.reshape(-1),
value=distribution,
isomin=colorbar_min,
isomax=colorbar_max,
opacity=opacity,
surface_count=surface_number
))
if save_file is not None:
import plotly.io as pio
fmt = save_file.split('.')[-1]
if fmt not in ['png', 'jpg', 'jpeg', 'webp', 'svg', 'pdf', 'eps']:
raise ValueError("The format {} is not supported in plotly!".format(fmt))
try:
pio.write_image(fig, format=fmt, file=save_file)
except ValueError:
os.system('python3 -m pip install --upgrade kaleido')
pio.write_image(fig, format=fmt, file=save_file)
if os.path.exists('offline_plot.html'):
os.rename('offline_plot.html', 'offline_plot.html.bak')
if show:
offline.plot(fig, filename='offline_plot.html', auto_open=True)
else:
offline.plot(fig, filename='offline_plot.html', auto_open=False)
为了方便复现,添加了异常捕获的方法。最终展示结果如下:
另外,可以从不同角度观察结果:
以上数据与前面章节展示的断层扫描图使用的是相同数据。在等高面结果中,可以看到三维空间中存在一条低密度的“通路”。这个展示图像显示效果良好,速度也相当可观,没有明显的卡顿。
在一维空间下,可以使用二维函数y=f(x)表示密度,在二维空间下,可以使用三维函数z=f(x,y)表示密度。而在三维空间下,密度表示是一个四维函数:q=f(x,y,z)。在三维空间中,我们可以将密度投影到一个三维的等高曲面上,这个曲面称为等高面。本文介绍了一个Python中性能较好的绘制等高面的工具:Plotly。
本文首发链接为:
https://www.cnblogs.com/dechinphy/p/iso-surface.html
作者ID:DechinPhy
更多原著文章:
https://www.cnblogs.com/dechinphy/
请博主喝咖啡:
https://www.cnblogs.com/dechinphy/gallery/image/379634.html