技术背景

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

等高线作图

如果是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作图三维等高面的更多相关文章

  1. 教孩子学编程 python语言版PDF高清完整版免费下载|百度云盘|Python入门

    百度云盘:教孩子学编程 python语言版PDF高清完整版免费下载 提取码:mnma 内容简介 本书属于no starch的经典系列之一,英文版在美国受到读者欢迎.本书全彩印刷,寓教于乐,易于学习:读 ...

  2. Python快速入门PDF高清完整版免费下载|百度云盘

    百度云盘:Python快速入门PDF高清完整版免费下载 提取码:w5y8 内容简介 这是一本Python快速入门书,基于Python 3.6编写.本书分为4部分,第一部分讲解Python的基础知识,对 ...

  3. 【python】python函数式编程、高阶函数

    1.map() : python内置的高阶函数,接收一个函数f和一个list,并通过把函数f依次作用在list的每个元素上,得到一个新的list并            返回. def f(x): r ...

  4. python 函数式编程:高阶函数,map/reduce

    python 函数式编程:高阶函数,map/reduce #函数式编程 #函数式编程一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数 #(一)高阶函数 f=abs f print ...

  5. python入门16 递归函数 高阶函数

    递归函数:函数内部调用自身.(要注意跳出条件,否则会死循环) 高阶函数:函数的参数包含函数 递归函数 #coding:utf-8 #/usr/bin/python """ ...

  6. python内置常用高阶函数(列出了5个常用的)

    原文使用的是python2,现修改为python3,全部都实际输出过,可以运行. 引用自:http://www.cnblogs.com/duyaya/p/8562898.html https://bl ...

  7. Matlab vs Python 作图

    -- Matlab 作图示例 x=-3:0.00003:3; y1=sin(x)./x; y2=x./sin(x); plot(x,y1,x,y2); -- Python 作图示例 import nu ...

  8. 参考分享《Python深度学习》高清中文版pdf+高清英文版pdf+源代码

    学习深度学习时,我想<Python深度学习>应该是大多数机器学习爱好者必读的书.书最大的优点是框架性,能提供一个"整体视角",在脑中建立一个完整的地图,知道哪些常用哪些 ...

  9. 从零开始学Python网络爬虫PDF高清完整版免费下载|百度网盘

    百度网盘:从零开始学Python网络爬虫PDF高清完整版免费下载 提取码:wy36 目录 前言第1章 Python零基础语法入门 11.1 Python与PyCharm安装 11.1.1 Python ...

  10. Python编程无师自通PDF高清完整版免费下载|百度网盘

    百度网盘:Python编程无师自通PDF高清完整版免费下载 提取码:cx73 内容介绍 畅销Python编程类入门书,美国亚马逊Kindle编程类排行榜榜一. 作者从文科毕业,通过自学编程转行为专业程 ...

随机推荐

  1. openGauss单机部署

    openGauss 单机部署 一.安装环境 操作系统:虚拟机 VMware.CentOS7.9 环境设置: (1)虚拟机内存 3G.磁盘 100G (2)系统版本修改 一开始使用了 centos8,无 ...

  2. VSCode如何通过Ctrl+P快速打开node_modules中的文件

    背景 咱们新建一个NodeJS项目,必然会安装许多依赖包,因此经常需要查阅某些依赖包的源码文件.但是,由于node_modules目录包含的文件太多,出于性能考虑,在VSCode中默认情况下是禁止搜索 ...

  3. Linux之识别HBA的WWN

    一.概念 FC HBA,也即Fibre Channel Host Bus Adapter,光纤通道主机适配器,简称光纤适配器. 在FC网络环境中,主机需要和FC网络.FC存储设备(SAN磁盘阵列)连接 ...

  4. 模型可解释之个体条件期望曲线(Individual Conditional Expectation)

    ICE是模型可解释中,作为局部可解释的一个分支. 本质上就对每一个样本,通过改变某个特征取值而观测模型做出的预测变化的方式以解释模型.

  5. redis 简单整理——redis 的键管理[七]

    前言 简单整理一下redis的键管理. 正文 单个键管理 键重命名 rename key newkey 为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey 不存在时 ...

  6. redis 简单整理——redis 的字符串基本结构和命令[二]

    前言 简单介绍一下redis的基本结构和命令. 正文 redis有5种基本结构: 字符串 哈希 列表 集合 有序集合 那么就来看下其基本命令吧. 通用命令键: keys * 查看全部键,一般不怎么用. ...

  7. K8s集群nginx-ingress监控告警最佳实践

    本文分享自华为云社区<K8s集群nginx-ingress监控告警最佳实践>,作者:可以交个朋友. 一 背景 nginx-ingress作为K8s集群中的关键组成部分.主要负责k8s集群中 ...

  8. T-SQL中执行存储过程与C#执行同样操作的比较

    1 exec sp_executesql N"UPDATE [dbo].[Courses] 2 SET [Title] = @0 3 WHERE (([CourseID] = @1) AND ...

  9. 数据结构实验代码分享 - 3 (哈夫曼树 / HuffmanTree)

    哈夫曼编码/ 译码系统(树应用) [问题描述] 任意给定一个仅由 26 个大写英文字母组成的字符序列,根据哈夫曼编码算法,求得每个字符的哈夫曼编码. 要求: 1)输入一个由 26 个英文字母组成的字符 ...

  10. 聊聊 Linux iowait

    哈喽大家好,我是咸鱼. 我们在使用 top 命令来查看 Linux 系统整体 CPU 使用情况的时候,往往看的是下面这一列: %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 ...