回顾
在走进Matplotlib世界(十)中,我们介绍了Matplotlib中的几个3D图表,包括3D线状图、3D散点图、线框图、曲面图和三角形曲面图的基本用法。今天我们介绍一下剩下的几个3D图表:3D等高线图,3D填充等高线图、多边形图、3D柱状图和3D箭图。
3D等高线图
Matplotlib中使用Axes3D的contour()方法绘制等高线图。contour()方法的常用参数及意义如下。
x,y,z:作为数据值作为一维数组。
extend3d:是否在3d中扩展轮廓(默认值:False)。
stride:用于延伸轮廓的步幅(步幅大小)。
zdir:要使用的方向:x、y或z(默认)。
offset:偏移。如果指定了偏移,则在垂直于Zdir的平面上绘制该位置上轮廓线的投影。
基本用法如下。?
from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt from matplotlib import cm fig = plt.figure(figsize=(17, 5)) ax1 = fig.add_subplot(131, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) cset = ax1.contour(X, Y, Z, cmap=cm.coolwarm) ax1.clabel(cset, fontsize=9, inline=1) ax2 = fig.add_subplot(132, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) cset = ax2.contour(X, Y, Z, extend3d=True, cmap=cm.coolwarm) ax2.clabel(cset, fontsize=9, inline=1) ax3 = fig.add_subplot(133, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax3.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) cset = ax3.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) cset = ax3.contour(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) cset = ax3.contour(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax3.set_xlabel('X') ax3.set_xlim(-40, 40) ax3.set_ylabel('Y') ax3.set_ylim(-40, 40) ax3.set_zlabel('Z') ax3.set_zlim(-100, 100) plt.show()
以上代码创建了三个不同的3D等高线图,运行结果如下图所示。
3D填充等高线图
3D填充等高线图其实就是对3D等高线图进行填充,Matplotlib中使用Axes3D的contourf()方法绘制3D填充等高线。我们针对上述的第一和第三个3D等高线图数据绘制3D填充等高线图。?
from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt from matplotlib import cm fig = plt.figure(figsize=(11, 5)) ax1 = fig.add_subplot(121, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) cset = ax1.contourf(X, Y, Z, cmap=cm.coolwarm) ax1.clabel(cset, fontsize=9, inline=1) ax2 = fig.add_subplot(122, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax2.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) cset = ax2.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) cset = ax2.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) cset = ax2.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax2.set_xlabel('X') ax2.set_xlim(-40, 40) ax2.set_ylabel('Y') ax2.set_ylim(-40, 40) ax2.set_zlabel('Z') ax2.set_zlim(-100, 100) plt.show()
运行结果如下图所示。
多边形图
多边形图顾名思义就是类似多边形的一个图表,Matplotlib中使用Axes3D的add_collection3d()方法绘制多边形图,基本用法如下。我们在三维坐标系下绘制4个多边形,为便于区别,我们使用4种颜色。?
from mpl_toolkits.mplot3d import Axes3D from matplotlib.collections import PolyCollection import matplotlib.pyplot as plt from matplotlib import colors as mcolors import numpy as np fig = plt.figure(figsize=(6, 5)) ax = fig.gca(projection='3d') def cc(arg): return mcolors.to_rgba(arg, alpha=0.6) xs = np.arange(0, 10, 0.4) verts = [] zs = [0.0, 1.0, 2.0, 3.0] for z in zs: ys = np.random.rand(len(xs)) ys[0], ys[-1] = 0, 0 verts.append(list(zip(xs, ys))) poly = PolyCollection(verts, facecolors=[cc('r'), cc('g'), cc('b'), cc('y')]) poly.set_alpha(0.7) ax.add_collection3d(poly, zs=zs, zdir='y') ax.set_xlabel('X') ax.set_xlim3d(0, 10) ax.set_ylabel('Y') ax.set_ylim3d(-1, 4) ax.set_zlabel('Z') ax.set_zlim3d(0, 1) plt.show()
严格来讲,我们绘制的多边形并不是3D图表,只是在3维坐标系下绘制了4个二维多边形。运行结果如下图所示。
3D柱状图
3D柱状图就是在三维坐标系下的柱状图,Matplotlib中使用Axes3D的bar()方法绘制3D柱状图,常用参数及其含义如下。
left:柱状图左侧的X坐标。
height:柱状图的高度。
zs:z坐标,如果指定了一个值,则它们都将放置在同一个z上。
zdir:在绘制二维集时用作z(“x”、“y”或“z”)的方向。
基本用法如下。?
from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np ig = plt.figure(figsize=(6, 5)) ax = fig.add_subplot(111, projection='3d') for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]): xs = np.arange(20) ys = np.random.rand(20) # You can provide either a single color or an array. To demonstrate this, # the first bar of each set will be colored cyan. cs = [c] * len(xs) cs[0] = 'c' ax.bar(xs, ys, zs=z, zdir='y', color=cs, alpha=0.8) axset_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') pl.show()
与多边形图一样,我们绘制的3D柱状图实际上并不是3D图表,只是在3维坐标系下绘制的柱状图。运行结果如下图所示。
3D箭图
3D箭图就是一个箭头的三维区域,Matplotlib中使用Axes3D的quiver()方法绘制箭图,常用参数及其含义如下。
x,y,z:箭头位置的X、Y和Z坐标(默认为箭头的尾部)。
u,v,w:箭头向量的x、y和z分量。参数可以是数组或标量,也可以是屏蔽数组。如果任何参数中的元素被屏蔽,则不会绘制相应的quiver元素。
length:每个震颤的长度,默认为1.0,单位与轴相同。
arrow_length_ratio:箭头相对于箭袋的比率,默认为0.3。
pivot:位于网格点的箭头部分。箭头围绕该点旋转,因此命名为Pivot。默认为“tail”。
normalize:正则化。如果为True,则所有箭头的长度都相同。默认为False,其中箭头的长度将根据u、v、w值的不同而不同。
基本用法如下,哇满绘制一系列箭头。?
from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt import numpy as np fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') # Make the grid 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)) # Make the direction data for the arrows 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)) ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True) plt.show()
运行结果如下图所示。
3D图中的2D数据
在三维坐标系中,我们可以任取二维展示我们的2D数据。下面我们分别在(x,y)平面下绘制线状图,在(x,z)平面下绘制散点图。?
from mpl_toolkits.mplot3d import Axes3D import numpy as np import matplotlib.pyplot as plt fig = plt.figure(figsize=(8, 6)) ax = fig.gca(projection='3d') # 以x轴、y轴为面绘制线状图 x = np.linspace(0, 1, 100) y = np.sin(x * 2 * np.pi) / 2 + 0.5 ax.plot(x, y, zs=0, zdir='z', label='(x,y)下的线状图') # 以x轴、z轴为面绘制散点图 colors = ('r', 'g', 'b', 'k') x = np.random.sample(20*len(colors)) y = np.random.sample(20*len(colors)) c_list = [] for c in colors: c_list.extend([c]*20) ax.scatter(x, y, zs=0, zdir='y', c=c_list, label='(x,z)下的散点图') ax.legend() ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_zlim(0, 1) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') # Customize the view angle so it's easier to see that the scatter points lie # on the plane y=0 ax.view_init(elev=20., azim=-35) plt.show()
运行后结果如下图所示。
3D图表添加文本
和2D图表一样,我们也可以在三维坐标系中添加文本,Matplotlib中使用Axes3D的text()方法给3D图表添加文本。text()方法的常用参数和意义如下。
x,y,z:确定文本在三维坐标线中的位置。
s:文本内容。
zdir:设置用作z方向的方向。
此外,还可以使用text2D()方法在三维坐标系所在平面添加文本。下面是绘制文本的基本用法。
from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt fig = plt.figure(figsize=(8, 6)) ax = fig.gca(projection='3d') 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) ax.text(9, 0, 0, "red", color='red') # 前两个参数表示位置 (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 axis') ax.set_ylabel('Y axis') ax.set_zlabel('Z axis') plt.show()
运行后结果如下图所示。
Matplotlib中的3D图表就介绍到这里了。感谢大家的关注,欢迎批评指正,一起交流~
???