python如何用matplotlib创建三维图表


Posted in Python onJanuary 26, 2021

Matplotlib 最开始被设计为仅支持二维的图表。到 1.0 版本发布左右,一些三维图表的工具在二维展示的基础上被创建了出来,结果就是 Matplotlib 提供了一个方便的(同时也是有限的)的可用于三维数据可视化的一套工具。三维图表可以使用载入mplot3d工具包来激活,这个包会随着 Matplotlib 自动安装:

from mpl_toolkits import mplot3d

一旦模块被导入,三维 axes 就可以像其他普通 axes 一样通过关键字参数projection='3d'来创建:

import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = plt.axes(projection='3d')
plt.show()

python如何用matplotlib创建三维图表

三维 axes 激活后,我们可以在上面绘制不同的三维图表类型。三维图表在 notebook 中使用交互式图表展示会优于使用静态展示;回忆我们前面介绍过,你可以使用%matplotlib notebook而不是%matplotlib inline来激活交互式展示模式。

三维的点和线

三维图表中最基础的是使用(x, y, z)坐标定义的一根线或散点的集合。前面介绍过普通的二维图表,作为类比,使用ax.plot3D和ax.scatter3D函数可以创建三维折线和散点图。这两个函数的签名与二维的版本基本一致,你可以参考[简单折线图]和[简单散点图]来复习一下这部分的内容。下面我们绘制一个三维中的三角螺旋,在线的附近在绘制一些随机的点:

ax = plt.axes(projection='3d')

# 三维螺旋线的数据
zline = np.linspace(0, 15, 1000)
xline = np.sin(zline)
yline = np.cos(zline)
ax.plot3D(xline, yline, zline, 'gray')

# 三维散点的数据
zdata = 15 * np.random.random(100)
xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens');

python如何用matplotlib创建三维图表

注意默认情况下,图中的散点会有透明度的区别,用于体现在图中散点的深度。虽然三维效果在静态图像中难以显示,你可以使用交互式的视图来获得更佳的三维直观效果。

三维轮廓图

类似于我们在[密度和轮廓图]中介绍的内容,mplot3d也包含着能够创建三维浮雕图像的工具。就像二维的ax.contour图表,ax.contour3D要求输入数据的格式是二维普通网格上计算得到的 Z 轴的数据值。下面我们展示一个三维的正弦函数轮廓图:

def f(x, y):
  return np.sin(np.sqrt(x ** 2 + y ** 2))

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

X, Y = np.meshgrid(x, y)
Z = f(X, Y)
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.contour3D(X, Y, Z, 50, cmap='binary')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z');

python如何用matplotlib创建三维图表

有时候默认的视角角度不是最理想的,在这种情况下我们可以使用view_init函数来设置水平角和方位角。在下面的例子中,我们使用的是 60° 的水平角(即以 60° 俯视 x-y 平面)和 35° 的方位角(即将 z 轴逆时针旋转 35°):

ax.view_init(60, 35)
fig

python如何用matplotlib创建三维图表

同样,注意到当使用 Matplotlib 交互式展示是,这样的旋转可以通过鼠标点击和拖拽来实现。

框线图和表面图

使用网格数据生成的三维图表还有框线图和表面图。这两种图表将网格数据投射到特定的三维表面,能够使得结果图像非常直观和具有说服力。下面是一个框线图的例子:

fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_wireframe(X, Y, Z, color='black')
ax.set_title('wireframe');

python如何用matplotlib创建三维图表

表面图类似框线图,区别在于每个框线构成的多边形都使用颜色进行了填充。添加色图用于填充多边形能够让图形表面展示出来:

ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
        cmap='viridis', edgecolor='none')
ax.set_title('surface');

python如何用matplotlib创建三维图表

注意虽然每个颜色填充的表面都是二维的,但是表面的边缘不需要是直线构成的。下面的例子使用surface3D绘制了一个部分极坐标网格,能够让我们切入到函数内部观察效果:

r = np.linspace(0, 6, 20)
theta = np.linspace(-0.9 * np.pi, 0.8 * np.pi, 40)
r, theta = np.meshgrid(r, theta)

X = r * np.sin(theta)
Y = r * np.cos(theta)
Z = f(X, Y)

ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
        cmap='viridis', edgecolor='none');

python如何用matplotlib创建三维图表

表面三角剖分

在一些应用场合中,上面的这种均匀网格绘制的图表方式太过于局限和不方便。在这些情况下,三角剖分的图表可以派上用场。如果我们并不是使用笛卡尔坐标系或极坐标系的网格来绘制三维图表,而是使用一组随机的点来绘制三维图表呢?

theta = 2 * np.pi * np.random.random(1000)
r = 6 * np.random.random(1000)
x = np.ravel(r * np.sin(theta))
y = np.ravel(r * np.cos(theta))
z = f(x, y)
ax = plt.axes(projection='3d')
ax.scatter(x, y, z, c=z, cmap='viridis', linewidth=0.5);

python如何用matplotlib创建三维图表

上图并未形象的表示出表面情况。这种情况下我们可以使用ax.plot_trisurf函数,它能首先根据我们的数据输入找到各点内在的三角函数形式,然后绘制表面(注意的是这里的 x,y,z 是一维的数组):

ax = plt.axes(projection='3d')
ax.plot_trisurf(x, y, z,
        cmap='viridis', edgecolor='none');

python如何用matplotlib创建三维图表

上图的结果很显然没有使用网格绘制表面图那么清晰,但是对于我们并不是使用函数构建数据样本(数据样本通常来自真实世界的采样)的情况下,这能提供很大的帮助。例如我们下面会看到,能使用这种方法绘制一条三维的莫比乌斯环。

例子:绘制莫比乌斯环

python如何用matplotlib创建三维图表

theta = np.linspace(0, 2 * np.pi, 30)
w = np.linspace(-0.25, 0.25, 8)
w, theta = np.meshgrid(w, theta)

python如何用matplotlib创建三维图表

phi = 0.5 * theta

现在我们已经有了所有需要获得三维坐标值的参数了。我们定义  为每个坐标点距离环形中间的位置,使用它来计算最终(x,y,z)  三维坐标系的坐标值:

# r是坐标点距离环形中心的距离值
r = 1 + w * np.cos(phi)
# 利用简单的三角函数知识算得x,y,z坐标值
x = np.ravel(r * np.cos(theta))
y = np.ravel(r * np.sin(theta))
z = np.ravel(w * np.sin(phi))

最后,为了绘制对象,我们必须保证三角剖分是正确的。实现这个最好的方法是在底层的参数上面实现三角剖分,最后让 Matplotlib 将这个三角剖分投射到三维空间中形成莫比乌斯环。下面的代码最终绘制图形:

# 在底层参数的基础上进行三角剖分
from matplotlib.tri import Triangulation
tri = Triangulation(np.ravel(w), np.ravel(theta))

ax = plt.axes(projection='3d')
ax.plot_trisurf(x, y, z, triangles=tri.triangles,
        cmap='viridis', linewidths=0.2);

ax.set_xlim(-1, 1); ax.set_ylim(-1, 1); ax.set_zlim(-1, 1);

python如何用matplotlib创建三维图表

 结合这些技巧,能够为你提供在 Matplotlib 创建和展现大量三维对象和模式的能力。

以上就是python如何用matplotlib创建三维图表的详细内容,更多关于python用matplotlib创建三维图表的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python中声明只包含一个元素的元组数据方法
Aug 25 Python
Django Highcharts制作图表
Aug 27 Python
Tornado 多进程实现分析详解
Jan 12 Python
python3爬取淘宝信息代码分析
Feb 10 Python
python3.x上post发送json数据
Mar 04 Python
解决python 输出是省略号的问题
Apr 19 Python
Scrapy基于selenium结合爬取淘宝的实例讲解
Jun 13 Python
Python 线性回归分析以及评价指标详解
Apr 02 Python
python与pycharm有何区别
Jul 01 Python
Python通过zookeeper实现分布式服务代码解析
Jul 22 Python
如何通过安装HomeBrew来安装Python3
Dec 23 Python
教你怎么用PyCharm为同一服务器配置多个python解释器
May 31 Python
python软件测试Jmeter性能测试JDBC Request(结合数据库)的使用详解
Jan 26 #Python
Python数据模型与Python对象模型的相关总结
Jan 26 #Python
使用豆瓣源来安装python中的第三方库方法
Jan 26 #Python
详解用selenium来下载小姐姐图片并保存
Jan 26 #Python
selenium与xpath之获取指定位置的元素的实现
Jan 26 #Python
详解Python中的Lock和Rlock
Jan 26 #Python
5分钟快速掌握Python定时任务框架的实现
Jan 26 #Python
You might like
在DC的漫画和电影中,蝙蝠侠的宿敌,小丑的真名是什么?
2020/04/09 欧美动漫
SSI指令
2006/11/25 PHP
使用php计算排列组合的方法
2013/11/13 PHP
php天翼开放平台短信发送接口实现方法
2014/12/22 PHP
浅谈PHP定义命令空间的几个注意点(推荐)
2016/10/29 PHP
php数组指针操作详解
2017/02/14 PHP
PHP实现二维数组按照指定的字段进行排序算法示例
2019/04/23 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
把html页面的部分内容保存成新的html文件的jquery代码
2009/11/12 Javascript
javascript 折半查找字符在数组中的位置(有序列表)
2010/12/09 Javascript
Three.js源码阅读笔记(物体是如何组织的)
2012/12/27 Javascript
javascript当中的代码嗅探扩展原生对象和原型(prototype)
2013/01/11 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
jquery京东商城双11焦点图多图广告特效代码分享
2015/09/06 Javascript
javascript HTML+CSS实现经典橙色导航菜单
2016/02/16 Javascript
3kb jQuery代码搞定各种树形选择的实现方法
2016/06/10 Javascript
artDialog+plupload实现多文件上传
2016/07/19 Javascript
jquery精度计算代码 jquery指定精确小数位
2017/02/06 Javascript
canvas绘制一个常用的emoji表情
2017/03/30 Javascript
angularjs中的$eval方法详解
2017/04/24 Javascript
vue-scroller记录滚动位置的示例代码
2018/01/17 Javascript
vue 虚拟dom的patch源码分析
2018/03/01 Javascript
js中getter和setter用法实例分析
2018/08/14 Javascript
微信小程序日历组件使用方法详解
2018/12/29 Javascript
JavaScript中import用法总结
2019/01/20 Javascript
浅谈layui框架自带分页和表格重载的接口解析问题
2019/09/11 Javascript
js数组相减简单示例【删除a数组所有与b数组相同元素】
2020/03/04 Javascript
JS实现密码框效果
2020/09/10 Javascript
获取python的list中含有重复值的index方法
2018/06/27 Python
django开发post接口简单案例,获取参数值的方法
2018/12/11 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
匡威西班牙官网:Converse西班牙
2019/10/01 全球购物
服务行业个人求职的自我评价
2013/12/12 职场文书
小学生教师节演讲稿
2014/09/03 职场文书
公司领导班子群众路线四风问题对照检查材料
2014/10/02 职场文书
粗暴解决CUDA out of memory的问题
2021/05/22 Python