Python作图三维等高面

python · 浏览次数 : 0

小编点评

**技术背景** * 等高线:在二维平面上表示“高度一致”的曲面。 * 等高面:在三维空间中“高度一致”的曲面。 * 等高表面:四维函数,表示密度。 **Matplotlib 示例** ```python import matplotlib.pyplot as plt # 创建三维曲面数据 z_level = np.linspace(np.min(Z), np.max(Z), 7) # 创建等高表面 fig, ax = plt.subplots() ax.contour(X, Y, Z, levels=levels) # 显示图像 plt.show() ``` **其他工具** * Plotly:可以用来绘制等高面。 * Plotly 的等高面示例: ```python import plotly.graph_objects as go # 创建数据 x, y, z = np.meshgrid(z1, z2, z3) distribution = np.random.rand(m, n, p) # 创建等高表面 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)) # 保存等高表面 fig.write_image("iso_surface.html") ``` **总结** 等高线是三维曲面的一个特殊情况,可以使用 Matplotlib 或 Plotly 等工具绘制。等高面可以用来表示三维空间中的密度分布,并可以用于各种数据可视化任务。

正文

技术背景

对于等高线,大家都是比较熟悉的,因为日常生活中遇到的山体和水面,都可以用一系列的等高线描绘出来。而等高面,顾名思义,就是在三维空间“高度一致”的曲面。当然了,在二维平面上我们所谓的“高度”实际上就是第三个维度的值,但是三维曲面所谓的“高度”,实际上我们可以理解为密度。“高度”越高,“密度”越大。

等高线作图

如果是Python中画等高线,这个用Matplotlib就可以实现,这里就直接放一个Matplotlib的官方示例

import matplotlib.pyplot as plt
import numpy as np

plt.style.use('_mpl-gallery-nogrid')

# make data
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)

# plot
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)。在作图函数的内部我们可以用一个meshgrid的操作对z1,z2,z3做展开,但是准备数据阶段我们就尽可能的简单就行了。这里直接上代码:

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:
        # 确保plotly正常安装
        os.system('python3 -m pip install --upgrade plotly')
        import plotly.graph_objects as go
        import plotly.offline as offline
    # Plotly作图要求数据展平,这里我们手动操作
    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]
        # Plotly支持的图片导出格式就是这几种了
        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:
            # 导出图片需要依赖kaleido环境
            os.system('python3 -m pip install --upgrade kaleido')
            pio.write_image(fig, format=fmt, file=save_file)
    # Plotly生成的结果是以html格式保存的,我们做了一个简单的本地备份
    if os.path.exists('offline_plot.html'):
        os.rename('offline_plot.html', 'offline_plot.html.bak')
    # 生成html文件以后选择是否需要打开,默认生成结束之后自动在浏览器打开图像
    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

与Python作图三维等高面相似的内容:

Python作图三维等高面

在一维空间下,我们要表示密度时可以给出一个二维的函数y=f(x),画出来是一条二维平面上的曲线。在二维空间下,我们要表示密度可以使用一个三维的函数z=f(x,y),画出来是一个三维空间的曲面。而三维空间下,密度表示是一个四维的函数:q=f(x,y,z),这个密度我们在三维空间已经没有办法用线或者面去...

Python图像处理丨5种图像处理特效

摘要:本篇文章主要讲解了图像常见的特效处理,从处理效果图、算法原理、代码实现三个步骤进行详细讲解,涉及图像素描特效、怀旧特效、光照特效、流年特效、图像滤镜等。 本文分享自华为云社区《[Python图像处理] 二十五.图像特效处理之素描、怀旧、光照、流年以及滤镜特效》,作者: eastmount。 一

如何使用Python和Plotly绘制3D图形

本文分享自华为云社区《Plotly绘制3D图形》 ,作者:柠檬味拥抱。 在数据可视化领域,三维图形是一种强大的工具,可以展示数据之间的复杂关系和结构。Python语言拥有丰富的数据可视化库,其中Plotly是一款流行的工具,提供了绘制高质量三维图形的功能。本文将介绍如何使用Python和Plotly

Python从0到1丨带你认识图像平滑的三种线性滤波

摘要:常用于消除噪声的图像平滑方法包括三种线性滤波(均值滤波、方框滤波、高斯滤波)和两种非线性滤波(中值滤波、双边滤波),本文将详细讲解三种线性滤波方法。 本文分享自华为云社区《[Python从零到壹] 五十五.图像增强及运算篇之图像平滑(均值滤波、方框滤波、高斯滤波)》,作者:eastmount。

从0到1学Python丨图像平滑方法的两种非线性滤波:中值滤波、双边滤波

摘要:常用于消除噪声的图像平滑方法包括三种线性滤波(均值滤波、方框滤波、高斯滤波)和两种非线性滤波(中值滤波、双边滤波),本文将详细讲解两种非线性滤波方法。 本文分享自华为云社区《[Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波、双边滤波)》,作者:eastmount。 常用于

Python图像处理丨详解图像去雾处理方法

摘要:本文主要讲解ACE去雾算法、暗通道先验去雾算法以及雾化生成算法。 本文分享自华为云社区《[Python图像处理] 三十.图像预处理之图像去雾详解(ACE算法和暗通道先验去雾算法)丨【拜托了,物联网!】》,作者:eastmount 。 一.图像去雾 随着社会的发展,环境污染逐渐加剧,越来越多的城

盘点Python 中字符串的常用操作

摘要:盘点 Python 中字符串的几个常用操作,对新手极度的友好。 本文分享自华为云社区《盘点 Python 中字符串的常用操作,对新手极度友好》,作者:TT-千叶 。 在 Python 中字符串的表达方式有四种 一对单引号一对双引号一对三个单引号一对三个双引号a = ‘abc’b= “abc”c

< Python全景系列-2 > Python数据类型大盘点

Python作为一门强大且灵活的编程语言,拥有丰富的数据类型系统。本文详细介绍了Python中的每一种数据类型,包括数值、序列、映射、集合、布尔和None类型。每种数据类型的特性、使用方式,以及在实际问题中的应用都将被深入探讨。此外,我们还将探讨Python的动态类型特性,以及如何在实际编程中充分利用这些数据类型来简化代码和提高效率。在文章的最后,我还将分享一个可能你还不知道,但非常有用的特性。

深入Python网络编程:从基础到实践

**Python,作为一种被广泛使用的高级编程语言,拥有许多优势,其中之一就是它的网络编程能力。Python的强大网络库如socket, requests, urllib, asyncio,等等,让它在网络编程中表现优秀。本文将深入探讨Python在网络编程中的应用,包括了基础的socket编程,到

一文带你搞清楚Python的多线程和多进程

本文分享自华为云社区《Python中的多线程与多进程编程大全【python指南】》,作者:柠檬味拥抱。 Python作为一种高级编程语言,提供了多种并发编程的方式,其中多线程与多进程是最常见的两种方式之一。在本文中,我们将探讨Python中多线程与多进程的概念、区别以及如何使用线程池与进程池来提高并