Python 数据分析三剑客之 Matplotlib(十):3D 图的绘制


文章目录


Matplotlib 系列文章:


专栏:


推荐学习资料与网站:


这里是一段物理防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 ITBOB。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106558131
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!

【01x00】了解 mplot3d Toolkit

mplot3d Toolkit 即 mplot3d 工具包,在 matplotlib 中使用 mplot3d 工具包可以绘制 3D 图。

mplot3d 官方文档:https://matplotlib.org/tutorials/toolkits/mplot3d.html

在 matplotlib 中,figure 为画布,axes 为绘图区,fig.add_subplot()plt.subplot() 方法均可以创建子图,在绘制 3D 图时,某些 2D 图的参数也适用于 3D 图,在本文的示例中,可能会用到的一些没有具体解释的函数或者参数,其用法均可在前面的系列文章中找到:

绘制 3D 图的步骤:创建 Axes3D 对象,然后调用 Axes3D 的不同方法来绘制不同类型的 3D 图。以下介绍三种 Axes3D 对象创建的方法。

【01x01】Axes3D 对象创建方法一:Axes3D(fig)

在 Matplotlib 1.0.0 版本中,绘制 3D 图需要先导入 Axes3D 包,获取 figure 画布对象 fig 后,通过 Axes3D(fig) 方法来创建 Axes3D 对象,具体方法如下:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 获取 figure 画布并创建 Axes3D 对象
fig = plt.figure()
ax = Axes3D(fig)

# 数据坐标
z = np.linspace(0, 15, 1000)
x = np.sin(z)
y = np.cos(z)

# 绘制线性图
ax.plot(x, y, z)
plt.show()

【01x02】Axes3D 对象创建方法二:add_subplot

在 Matplotlib 3.2.0 版本中,绘制 3D 图可以通过创建子图,然后指定 projection 参数 为 3d 即可,返回的 ax 为 Axes3D 对象,以下两种方法均可:

import numpy as np
import matplotlib.pyplot as plt

# 获取 figure 画布并通过子图创建 Axes3D 对象
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 数据坐标
z = np.linspace(0, 15, 1000)
x = np.sin(z)
y = np.cos(z)

# 绘制线性图
ax.plot(x, y, z)
plt.show()
import numpy as np
import matplotlib.pyplot as plt

# 通过子图创建 Axes3D 对象
ax = plt.subplot(111, projection='3d')

# 数据坐标
z = np.linspace(0, 15, 1000)
x = np.sin(z)
y = np.cos(z)

# 绘制线性图
ax.plot(x, y, z)
plt.show()

【01x03】Axes3D 对象创建方法三:gca

除了以上两种方法以外,还可以先获取画布对象 fig,再通过 fig.gca() 方法获取当前绘图区(gca = Get Current Axes),然后指定 projection 参数 为 3d 即可,返回的 ax 为 Axes3D 对象。

import numpy as np
import matplotlib.pyplot as plt

# 依次获取画布和绘图区并创建 Axes3D 对象
fig = plt.figure()
ax = fig.gca(projection='3d')

# 数据坐标
z = np.linspace(0, 15, 1000)
x = np.sin(z)
y = np.cos(z)

# 绘制线性图
ax.plot(x, y, z)
plt.show()

以上三种方法运行结果均为下图:

01

【02x00】cmap 与 colorbar

默认情况下,散点图、线性图、曲面图等将以纯色着色,但可以通过提供 cmap 参数支持颜色映射。cmap 参数用于设置一些特殊的颜色组合,如渐变色等,参数取值通常为 Colormap 中的值,具体取值可参见下图:

官方文档:https://matplotlib.org/tutorials/colors/colormaps.html

02

如果使用了 cmap 参数,则可以使用 pyplot.colorbar() 函数来绘制一个色条,即颜色对照条。

基本语法:matplotlib.pyplot.colorbar([mappable=None, cax=None, ax=None, **kw])

部分参数解释如下表,其他参数,如长度,宽度等请参考官方文档

参数 描述
mappable 要设置色条的图像对象,该参数对于 Figure.colorbar 方法是必需的,但对于 pyplot.colorbar 函数是可选的
cax 可选项,要绘制色条的轴
ax 可选项,设置色条的显示位置,通常在一个画布上有多个子图时使用
**kw 可选项,其他关键字参数,参考官方文档

【03x00】3D 线性图:Axes3D.plot

基本方法:Axes3D.plot(xs, ys[, zs, zdir='z', *args, **kwargs])

参数 描述
xs 一维数组,点的 x 轴坐标
ys 一维数组,点的 y 轴坐标
zs 一维数组,可选项,点的 z 轴坐标
zdir 可选项,在 3D 轴上绘制 2D 数据时,数据必须以 xs,ys 的形式传递,
若此时将 zdir 设置为 ‘y’,数据将会被绘制到 x-z 轴平面上,默认为 ‘z’
**kwargs 其他关键字参数,可选项,可参见 matplotlib.axes.Axes.plot
import numpy as np
import matplotlib.pyplot as plt

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 依次获取画布和绘图区并创建 Axes3D 对象
fig = plt.figure()
ax = fig.gca(projection='3d')

# 第一条3D线性图数据
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z1 = np.linspace(-2, 2, 100)
r = z1**2 + 1
x1 = r * np.sin(theta)
y1 = r * np.cos(theta)

# 第二条3D线性图数据
z2 = np.linspace(-3, 3, 100)
x2 = np.sin(z2)
y2 = np.cos(z2)

# 绘制3D线性图
ax.plot(x1, y1, z1, color='b', label='3D 线性图一')
ax.plot(x2, y2, z2, color='r', label='3D 线性图二')

# 设置标题、轴标签、图例,也可以直接使用 plt.title、plt.xlabel、plt.legend...
ax.set_title('绘制 3D 线性图示例', pad=15, fontsize='12')
ax.set_xlabel('x 轴', color='r', fontsize='12')
ax.set_ylabel('y 轴', color='g', fontsize='12')
ax.set_zlabel('z 轴', color='b', fontsize='12')
ax.legend()

plt.show()

03

【04x00】3D 散点图:Axes3D.scatter

基本方法:Axes3D.scatter(xs, ys[, zs=0, zdir='z', s=20, c=None, depthshade=True, *args, **kwargs])

参数 描述
xs 一维数组,点的 x 轴坐标
ys 一维数组,点的 y 轴坐标
zs 一维数组,可选项,点的 z 轴坐标
zdir 可选项,在 3D 轴上绘制 2D 数据时,数据必须以 xs,ys 的形式传递,
若此时将 zdir 设置为 ‘y’,数据将会被绘制到 x-z 轴平面上,默认为 ‘z’
s 标量或数组类型,可选项,标记的大小,默认 20
c 标记的颜色,可选项,可以是单个颜色或者一个颜色列表
支持英文颜色名称及其简写、十六进制颜色码等,更多颜色示例参见官网 Color Demo
depthshade bool 值,可选项,默认 True,是否为散点标记着色以提供深度外观
**kwargs 其他关键字参数,可选项,可参见 scatter
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 依次获取画布和绘图区并创建 Axes3D 对象
fig = plt.figure()
ax = fig.gca(projection='3d')
n = 100


def randrange(n, vmin, vmax):
    return (vmax - vmin)*np.random.rand(n) + vmin


'''
定义绘制 n 个随机点,设置每一组数据点的样式和范围
x轴数据位于[23,32]区间,y轴数据位于[0,100]区间,z轴数据位于[zlow,zhigh]区间
'''
for m, zlow, zhigh in [('o', -50, -25), ('^', -30, -5)]:
    xs = randrange(n, 23, 32)
    ys = randrange(n, 0, 100)
    zs = randrange(n, zlow, zhigh)
    ax.scatter(xs, ys, zs, marker=m)

# 设置标题、轴标签、图例,也可以直接使用 plt.title、plt.xlabel...
ax.set_title('绘制 3D 散点图示例', pad=15, fontsize='12')
ax.set_xlabel('x 轴', color='b')
ax.set_ylabel('y 轴', color='b')
ax.set_zlabel('z 轴', color='b')

plt.show()

04

【05x00】3D 线框图:Axes3D.plot_wireframe

基本方法:Axes3D.plot_wireframe(X, Y, Z[, *args, **kwargs])

参数 描述
X 二维数组,x 轴数据
Y 二维数组,y 轴数据
Z 二维数组,z 轴数据
**kwargs 其他关键字参数,可选项,如线条样式颜色等,可参见 Line3DCollection
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 获取 figure 画布并通过子图创建 Axes3D 对象
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')


# 定义Z轴坐标的生成方法
def f(m, n):
    return np.sin(np.sqrt(m ** 2 + n ** 2))


# 设置3D线框图数据
x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
# 生成网格点坐标矩阵,该方法在系列文章八中有具体介绍
X, Y = np.meshgrid(x, y)
Z = f(X, Y)

# 绘制3D线框图
ax.plot_wireframe(X, Y, Z, color='c')

# 设置标题、轴标签、图例,也可以直接使用 plt.title、plt.xlabel...
ax.set_title('绘制 3D 线框图示例', pad=15, fontsize='12')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.set_zlabel('z 轴')

plt.show()

05

【06x00】3D 曲面图:Axes3D.plot_surface

基本方法:Axes3D.plot_surface(X, Y, Z[, *args, vmin=None, vmax=None, **kwargs])

参数 描述
X 二维数组,x 轴数据
Y 二维数组,y 轴数据
Z 二维数组,z 轴数据
vmin / vmax 规定数据界限
**kwargs 其他关键字参数,可选项,如线条样式颜色等,可参见 Line3DCollection
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 获取 figure 画布并通过子图创建 Axes3D 对象
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 设置3D曲面图数据
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
# 生成网格点坐标矩阵,该方法在系列文章八中有具体介绍
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

# 绘制3D曲面图并添加色条(长度0.8)
surface = ax.plot_surface(X, Y, Z, cmap='rainbow', antialiased=False)
fig.colorbar(surface, shrink=0.8)

# 设置标题、轴标签、图例,也可以直接使用 plt.title、plt.xlabel...
ax.set_title('绘制 3D 曲面图示例', pad=15, fontsize='12')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.set_zlabel('z 轴')
# 调整观察角度和方位角,俯仰角25度,方位角40度
ax.view_init(25, 40)
# 设置Z轴刻度界限
ax.set_zlim(-2, 2)

plt.show()

06


这里是一段物理防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 ITBOB。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106558131
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!

【07x00】3D 柱状图:Axes3D.bar

基本方法:Axes3D.bar(left, height, zs=0, zdir='z', *args, **kwargs)

参数 描述
left 一维数组,柱状图最左侧位置的 x 坐标
height 一维数组,柱状图的高度(y 坐标)
zs 第 i 个多边形将出现在平面 y=zs[i] 上
zdir 可选项,在 3D 轴上绘制 2D 数据时,数据必须以 xs,ys 的形式传递,
若此时将 zdir 设置为 ‘y’,数据将会被绘制到 x-z 轴平面上,默认为 ‘z’
**kwargs 其他关键字参数,参见 matplotlib.axes.Axes.bar
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 获取 figure 画布并通过子图创建 Axes3D 对象
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

colors = ['r', 'g', 'b', 'y']
yticks = [3, 2, 1, 0]

# 设置3D柱状图数据并绘制图像
for c, k in zip(colors, yticks):
    xs = np.arange(20)
    ys = np.random.rand(20)
    cs = [c] * len(xs)
    ax.bar(xs, ys, zs=k, zdir='y', color=cs, alpha=0.8)

# 设置图像标题、坐标标签以及范围
ax.set_title('绘制 3D 柱状图示例', pad=15, fontsize='12')
ax.set_xlabel('X 轴')
ax.set_ylabel('Y 轴')
ax.set_zlabel('Z 轴')
ax.set_yticks(yticks)

plt.show()

07

【08x00】3D 箭头图:Axes3D.quiver

基本方法:Axes3D.quiver(X, Y, Z, U, V, W, length=1, arrow_length_ratio=0.3, pivot='tail', normalize=False, **kwargs)

参数 描述
X, Y, Z 数组形式,箭头位置的 x、y 和 z 轴坐标(默认为箭头尾部)
U, V, W 数组形式,箭头向量的 x、y 和 z 轴分量
length float 类型,每个箭筒的长度,默认为 1.0
arrow_length_ratio float 类型,箭头相对于箭身的比率,默认为 0.3
pivot 箭头在网格点上的位置;箭头围绕该点旋转,因此命名为 pivot,默认为 ‘tail’
可选项:'tail':尾部;'middle':中间;'tip':尖端
normalize bool 类型,如果为 True,则所有箭头的长度都将相同
默认为 False,即箭头的长度取决于 U、V、W 的值
**kwargs 其他关键字参数,参见 LineCollection
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 依次获取画布和绘图区并创建 Axes3D 对象
fig = plt.figure()
ax = fig.gca(projection='3d')

# 设置箭头位置
x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.8))

# 设置箭头数据
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) * np.sin(np.pi * z))

# 绘制 3D 箭头图
ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True)

# 设置图像标题、坐标标签
ax.set_title('绘制 3D 箭头图示例', pad=15, fontsize='12')
ax.set_xlabel('X 轴')
ax.set_ylabel('Y 轴')
ax.set_zlabel('Z 轴')

# 调整观察角度,俯仰角20度
ax.view_init(20)

plt.show()

08

【09x00】3D 等高线图:Axes3D.contour

基本方法:Axes3D.contour(X, Y, Z[, *args, extend3d=False, stride=5, zdir='z', offset=None, **kwargs])

参数 描述
X 一维数组,x 轴数据
Y 一维数组,y 轴数据
Z 一维数组,z 轴数据
extend3d bool 值,可选项,是否以 3D 延伸轮廓,默认 False
stride int 类型,可选项,用于延伸轮廓的步长
zdir 可选项,在 3D 轴上绘制 2D 数据时,数据必须以 xs,ys 的形式传递,
若此时将 zdir 设置为 ‘y’,数据将会被绘制到 x-z 轴平面上,默认为 ‘z’
offset 标量,可选项,如果指定,则在垂直于 zdir 的平面上的位置绘制轮廓线的投影
**kwargs 其他关键字参数,可选项,可参见 matplotlib.axes.Axes.contour
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 获取 figure 画布并通过子图创建 Axes3D 对象
fig = plt.figure(figsize=(8, 4.8))
ax = fig.add_subplot(111, projection='3d')

# 设置等高线数据
X = np.arange(-2.0, 2.0, 0.01)
Y = np.arange(-2.0, 2.0, 0.01)
# 生成网格点坐标矩阵
m, n = np.meshgrid(X, Y)


# 指定一个函数用于计算每个点的高度,也可以直接使用二维数组储存每个点的高度
def f(a, b):
    return (1 - b ** 5 + a ** 5) * np.exp(-a ** 2 - b ** 2)


# 绘制3D等高线图并添加色条图(长度0.8)
contour = ax.contour(X, Y, f(m, n), cmap='rainbow')
fig.colorbar(contour, shrink=0.8)

# 设置标题、轴标签、图例,也可以直接使用 plt.title、plt.xlabel...
ax.set_title('绘制 3D 等高线图示例', pad=15, fontsize='12')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.set_zlabel('z 轴')

plt.show()

09

【10x00】3D 等高线填充图:Axes3D.contourf

基本语法:Axes3D.contourf(X, Y, Z[, *args, zdir='z', offset=None, **kwargs])

参数 描述
X 一维数组,x 轴数据
Y 一维数组,y 轴数据
Z 一维数组,z 轴数据
zdir 可选项,在 3D 轴上绘制 2D 数据时,数据必须以 xs,ys 的形式传递,
若此时将 zdir 设置为 ‘y’,数据将会被绘制到 x-z 轴平面上,默认为 ‘z’
offset 标量,可选项,如果指定,则在垂直于 zdir 的平面上的位置绘制轮廓线的投影
**kwargs 其他关键字参数,可选项,可参见 matplotlib.axes.Axes.contourf
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 获取 figure 画布并通过子图创建 Axes3D 对象
fig = plt.figure(figsize=(8, 4.8))
ax = fig.add_subplot(111, projection='3d')

# 设置等高线数据
X = np.arange(-2.0, 2.0, 0.01)
Y = np.arange(-2.0, 2.0, 0.01)
# 生成网格点坐标矩阵
m, n = np.meshgrid(X, Y)


# 指定一个函数用于计算每个点的高度,也可以直接使用二维数组储存每个点的高度
def f(a, b):
    return (1 - b ** 5 + a ** 5) * np.exp(-a ** 2 - b ** 2)


# 绘制3D等高线图并添加色条图(长度0.8)
contourf = ax.contourf(X, Y, f(m, n), cmap='rainbow')
fig.colorbar(contourf, shrink=0.8)

# 设置标题、轴标签、图例,也可以直接使用 plt.title、plt.xlabel...
ax.set_title('绘制 3D 等高线填充图示例', pad=15, fontsize='12')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.set_zlabel('z 轴')

plt.show()

10

【11x00】3D 三角曲面图:Axes3D.plot_trisurf

基本方法:Axes3D.plot_trisurf(X, Y, Z[, *args, color=None, vmin=None, vmax=None, **kwargs])

参数 描述
X 一维数组,x 轴数据
Y 一维数组,y 轴数据
Z 一维数组,z 轴数据
color 曲面表面的颜色
vmin / vmax 规定数据界限
**kwargs 可选项,其他关键字参数,可参见 Poly3DCollection
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 获取 figure 画布并通过子图创建 Axes3D 对象
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

n_radii = 8
n_angles = 36

radii = np.linspace(0.125, 1.0, n_radii)
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)[..., np.newaxis]
x = np.append(0, (radii*np.cos(angles)).flatten())
y = np.append(0, (radii*np.sin(angles)).flatten())
z = np.sin(-x*y)

# 绘制3D三角曲面图并添加色条(长度0.8)
trisurf = ax.plot_trisurf(x, y, z, cmap='rainbow')
fig.colorbar(trisurf, shrink=0.8)

# 设置标题、轴标签、图例,也可以直接使用 plt.title、plt.xlabel...
ax.set_title('绘制 3D 三角曲面图示例', pad=15, fontsize='12')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.set_zlabel('z 轴')

plt.show()

11

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
fig = plt.figure(figsize=(15, 6))

# ============ 第一个示例图 ============ #

ax = fig.add_subplot(1, 2, 1, projection='3d')

u = np.linspace(0, 2.0 * np.pi, endpoint=True, num=50)
v = np.linspace(-0.5, 0.5, endpoint=True, num=10)
u, v = np.meshgrid(u, v)
u, v = u.flatten(), v.flatten()

x = (1 + 0.5 * v * np.cos(u / 2.0)) * np.cos(u)
y = (1 + 0.5 * v * np.cos(u / 2.0)) * np.sin(u)
z = 0.5 * v * np.sin(u / 2.0)

tri = mtri.Triangulation(u, v)

trisurf_1 = ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap='cool')
fig.colorbar(trisurf_1, shrink=0.8)
ax.set_zlim(-1, 1)

ax.set_title('绘制 3D 三角曲面图示例一', pad=15, fontsize='12')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.set_zlabel('z 轴')

# ============ 第二个示例图 ============ #

ax = fig.add_subplot(1, 2, 2, projection='3d')

n_angles = 36
n_radii = 8
min_radius = 0.25
radii = np.linspace(min_radius, 0.95, n_radii)

angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
angles[:, 1::2] += np.pi/n_angles

x = (radii*np.cos(angles)).flatten()
y = (radii*np.sin(angles)).flatten()
z = (np.cos(radii)*np.cos(3*angles)).flatten()

triang = mtri.Triangulation(x, y)

xmid = x[triang.triangles].mean(axis=1)
ymid = y[triang.triangles].mean(axis=1)
mask = xmid**2 + ymid**2 < min_radius**2
triang.set_mask(mask)

trisurf_2 = ax.plot_trisurf(triang, z, cmap='hsv')
fig.colorbar(trisurf_2, shrink=0.8)

ax.set_title('绘制 3D 三角曲面图示例二', pad=15, fontsize='12')
ax.set_xlabel('x 轴')
ax.set_ylabel('y 轴')
ax.set_zlabel('z 轴')

plt.show()

12

【12x00】将 2D 图像聚合到 3D 图像中:Axes3D.add_collection3d

基本方法:Axes3D.add_collection3d(col, zs=0, zdir='z')

参数 描述
col PolyCollection / LineCollection / PatchCollection 对象
zs 第 i 个多边形将出现在平面 y=zs[i] 上
zdir 可选项,在 3D 轴上绘制 2D 数据时,数据必须以 xs,ys 的形式传递,
若此时将 zdir 设置为 ‘y’,数据将会被绘制到 x-z 轴平面上,默认为 ‘z’

该函数一般用来向图形中添加 3D 集合对象,以下用一个示例来展示某个地区在不同年份和不同月份的降水量:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

fig = plt.figure()
ax = fig.gca(projection='3d')

np.random.seed(59)
month = np.arange(0, 13)
years = [2017, 2018, 2019, 2020]

precipitation = []
for year in years:
    value = np.random.rand(len(month)) * 300
    value[0], value[-1] = 0, 0
    precipitation.append(list(zip(month, value)))

poly = PolyCollection(precipitation, facecolors=['r', 'g', 'b', 'y'], alpha=.6)
ax.add_collection3d(poly, zs=years, zdir='y')

ax.set_title('2D 图像聚合到 3D 图像示例', pad=15, fontsize='12')
ax.set_xlabel('月份')
ax.set_ylabel('年份')
ax.set_zlabel('降水量')
ax.set_xlim3d(0, 12)
ax.set_ylim3d(2016, 2021)
ax.set_zlim3d(0, 300)

plt.show()

13

此外,该方法也常被用于绘制 3D 多边形图,即多边体,示例如下:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

fig = plt.figure()
ax = fig.gca(projection='3d')

# 六面体顶点和面
verts = [(0, 0, 0), (0, 1, 0), (1, 1, 0), (1, 0, 0), (0, 0, 1), (0, 1, 1), (1, 1, 1), (1, 0, 1)]
faces = [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [0, 3, 7, 4]]

# 获取每个面的顶点
poly3d = [[verts[vert_id] for vert_id in face] for face in faces]

# 绘制顶点
x, y, z = zip(*verts)
ax.scatter(x, y, z)
# 绘制多边形面
ax.add_collection3d(Poly3DCollection(poly3d, facecolors='w', linewidths=1, alpha=0.5))
# 绘制多边形的边
ax.add_collection3d(Line3DCollection(poly3d, colors='k', linewidths=0.5, linestyles=':'))

# 设置图像标题、坐标标签以及范围
ax.set_title('绘制多边体示例', pad=15, fontsize='12')
ax.set_xlabel('X 轴')
ax.set_ylabel('Y 轴')
ax.set_zlabel('Z 轴')
ax.set_xlim3d(-0.5, 1.5)
ax.set_ylim3d(-0.5, 1.5)
ax.set_zlim3d(-0.5, 1.5)
plt.show()

14

【13x00】3D 图添加文本描述:Axes3D.text

基本方法:Axes3D.text(x, y, z, s[, zdir=None, **kwargs])

参数 描述
x, y, z 文本位置的 x、y、z 轴坐标
s 要添加的文本
zdir 可选项,若将 zdir 设置为 ‘y’,文本将会被投影到 x-z 轴平面上,默认为 None
**kwargs 其他关键字参数,参见 matplotlib.text
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

# 依次获取画布和绘图区并创建 Axes3D 对象
fig = plt.figure()
ax = fig.gca(projection='3d')

# Demo 1: zdir 参数用法
zdirs = (None, 'x', 'y', 'z', (1, 1, 0), (1, 1, 1))
xs = (1, 4, 4, 9, 4, 1)
ys = (2, 5, 8, 10, 1, 2)
zs = (10, 3, 8, 9, 1, 8)

for zdir, x, y, z in zip(zdirs, xs, ys, zs):
    label = '(%d, %d, %d), dir=%s' % (x, y, z, zdir)
    ax.text(x, y, z, label, zdir)

# Demo 2:设置颜色
ax.text(9, 0, 0, "red", color='red')

# Demo 3: text2D,位置(0,0)为左下角,(1,1)为右上角。
ax.text2D(0.05, 0.95, "2D Text", transform=ax.transAxes)

# 设置坐标轴界限和标签
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_zlim(0, 10)
ax.set_xlabel('X 轴')
ax.set_ylabel('Y 轴')
ax.set_zlabel('Z 轴')

plt.show()

15


这里是一段物理防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 ITBOB。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106558131
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!