今天使用python中的matplotlib库绘制3D柱形图,以下就是画图的完成代码。
from mpl_toolkits.mplot3dimport Axes3D
import matplotlib.pyplotas plt
import numpyas np
#设置x轴取值
xedges = np.array([10,20,30,40,50,60,70])
#设置y轴取值
yedges = np.array([10,20,30,40,50,60,70])
#设置X,Y对应点的值。即原始数据。
hist =np.array( [[0.0964,0.1024,0.1043,0.1057,0.1072,0.1100],
[0.1027,0.1039,0.1057,0.1069,0.1078,0.1109],
[0.1046,0.1059,0.1061,0.1079,0.1085,0.1114],
[0.1068,0.1079,0.1084,0.1091,0.1096,0.1127],
[0.1091,0.1089,0.1107,0.1112,0.1118,0.1131],
[0.1102,0.1113,0.1121,0.1129,0.1133,0.1157]])
#生成图表对象。
fig = plt.figure()
#生成子图对象,类型为3d
ax = fig.add_subplot(111,projection='3d')
#设置作图点的坐标
xpos, ypos = np.meshgrid(xedges[:-1]-2.5 , yedges[:-1]-2.5 )
xpos = xpos.flatten('F')
ypos = ypos.flatten('F')
zpos = np.zeros_like(xpos)
#设置柱形图大小
dx =5 * np.ones_like(zpos)
dy = dx.copy()
dz = hist.flatten()
#设置坐标轴标签
ax.set_xlabel('R')
ax.set_ylabel('K')
ax.set_zlabel('Recall')
# x, y, z: array - like
# The coordinates of the anchor point of the bars.
# dx, dy, dz: scalar or array - like
# The width, depth, and height of the bars, respectively.
# minx = np.min(x)
# maxx = np.max(x + dx)
# miny = np.min(y)
# maxy = np.max(y + dy)
# minz = np.min(z)
# maxz = np.max(z + dz)
ax.bar3d(xpos, ypos, zpos, dx, dy, dz,color='b',zsort='average')
plt.show()
浏览过完整的绘图代码之后,接下来梳理一下制作3D柱形图的流程。
整个流程分为三个部分,导入绘图数据,设置图表参数以及图片展示。
1. 导入绘图数据。
一般而言,需要绘制3D柱形图的形式为:由两个维度的参数确定另外一个维度的值。即X轴的值与Y轴的值组合而成Z轴的值。因此在绘制3D柱形图时需要导入三组数据,即每个坐标轴的取值。
#设置x轴取值
xedges = np.array([10,20,30,40,50,60,70])
#设置y轴取值
yedges = np.array([10,20,30,40,50,60,70])
#设置X,Y对应点的值。即原始数据。
hist =np.array( [[0.0964,0.1024,0.1043,0.1057,0.1072,0.1100],
[0.1027,0.1039,0.1057,0.1069,0.1078,0.1109],
[0.1046,0.1059,0.1061,0.1079,0.1085,0.1114],
[0.1068,0.1079,0.1084,0.1091,0.1096,0.1127],
[0.1091,0.1089,0.1107,0.1112,0.1118,0.1131],
[0.1102,0.1113,0.1121,0.1129,0.1133,0.1157]])
需要注意的是,这里用于接收对应坐标轴数据的数据类型要用numpy库中的array方法转化,它属于numpy.ndarray类型。这是后续简便做图的准备之一,如果这里直接使用list类型来接收,那么后续步骤会报错。
2. 设置图表参数。
完成绘图数据的导入之后,接下来就需要设置图表参数。
- 首先创建一个图表对象并将其类型设置为3D
#生成图表对象。
fig = plt.figure()
#生成子图对象,类型为3d
ax = fig.add_subplot(111,projection='3d')
- 接着设置坐标轴的偏移程度。由于是做3D图形,则X轴与Y轴在做图点上需要适当偏离一些,这样绘制的图片从视觉上看起来会更自然。
#设置作图点的坐标
xpos, ypos = np.meshgrid(xedges[:-1]-2.5 , yedges[:-1]-2.5 )
xpos = xpos.flatten('F')
ypos = ypos.flatten('F')
zpos = np.zeros_like(xpos)
flatten()函数是将多维数组转换成一维数组,便于做图。
- 最后需要设置柱形图中圆柱的大小以及坐标轴的标签。
#设置柱形图大小
dx =5 * np.ones_like(zpos)
dy = dx.copy()
dz = hist.flatten()
#设置坐标轴标签
ax.set_xlabel('R')
ax.set_ylabel('K')
ax.set_zlabel('Recall')
3. 图片展示。
在完成了前两个步骤之后,接下来就需要调用绘图函数将绘图数据以及图表参数相结合并展示绘制而成的图片效果。
# x, y, z: array - like
# The coordinates of the anchor point of the bars.
# dx, dy, dz: scalar or array - like
# The width, depth, and height of the bars, respectively.
# minx = np.min(x)
# maxx = np.max(x + dx)
# miny = np.min(y)
# maxy = np.max(y + dy)
# minz = np.min(z)
# maxz = np.max(z + dz)
ax.bar3d(xpos, ypos, zpos, dx, dy, dz,color='b',zsort='average')
plt.show()
关于bar3d()函数,查阅其源代码发现内置的各参数的意义,包括在第2部分中提到的柱形图中柱子大小的设定,以及坐标轴的取值范围等。
不过比较尴尬的地方在于,从坐标轴取值范围的计算公式可知,它与柱子大小的参数绑定在一起,这就不利于灵活设置坐标轴的取值范围(相比于2d图形而言)。
上述代码的运行结果如下: