主页
手机版
扫描查看手机站
所在位置:首页 → 教程资讯 → 使用Python绘制等高线和等高面

使用Python绘制等高线和等高面

发布: 更新时间:2024-05-21 16:02:34

等高线在日常生活中是一种常见的地形表示方法,而等高面则是在三维空间中表示“高度一致”的曲面。在二维平面上,“高度”实际上是第三个维度的值,而在三维曲面中,“高度”可以理解为密度,即“高度”越高,“密度”越大。

使用Matplotlib绘制等高线

在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库来绘制等高面。

使用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

参考链接

  1. https://matplotlib.org/stable/plot_types/arrays/contour.html#sphx-glr-plot-types-arrays-contour-py
文章排行
软件上新 查看更多