Bar3d的官方示例并不好看,因为它不能根据柱的高度来显示不同的颜色。虽然bar3d函数可以设置每个柱子的颜色,但如何设置呢?右侧的颜色标尺又如何添加?本文将详细介绍代码和必要的解释。
Matplotlib是一个流行的Python可视化库,它可以用来创建各种图表,包括3D柱形图。bar3d函数可以用来创建3D柱形图,其中每个柱子由其长度、宽度和高度定义。下面是使用Matplotlib创建3D柱形图的基本步骤:
1.导入Matplotlib和Numpy库
1 2 3
| import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import LightSource
|
2.准备数据 为了创建3D柱形图,需要准备以下数据:
- x,y,z:每个柱子的底面中心坐标。
- dx, dy, dz:每个柱子的宽度、长度和高度。
- colors:每个柱子的颜色。
下面是一个示例数据:
1 2 3 4 5 6 7 8 9 10 11 12 13
| _x = np.arange(4) \\生成0到3的list _y = np.arange(5) \\生成0到4的list _xx, _yy = np.meshgrid(_x, _y) \\创建一个4行5列的网格坐标阵列,每个坐标为一个元组(_x,_y)。_xx,和_yy则分别为对应的4行5列坐标的x轴和y轴值。 x, y = _xx.ravel(), _yy.ravel() \\将x轴和y轴的4行5列网格的展开为一维列表。 dz = x + y \\柱子高度为x+y z = np.zeros_like(dz)
dx = dy = 1 \\柱子长宽为1,如果x或者y的ticks不同,比如x为[1,3,5],dx设置为2才能使柱子相互之间没有间距 \\设置每根柱子的颜色,最小值为蓝色,最大值为红色,中间值渐变。 if((dz.max() - dz.min()) != 0): colors = plt.cm.jet((dz.flatten() - dz.min()) / (dz.max() - dz.min())) else: colors = plt.cm.jet((dz.flatten() - dz.min()))
|
3.创建图形对象并绘制柱形图
1 2 3 4
| fig = plt.figure(figsize=(6, 5),dpi=300) ax = fig.add_subplot(111, projection='3d') ax.bar3d(x, y, z, dx, dy, dz, color=colors,shade=True) plt.show()
|
这将创建一个3D柱形图,其中每个柱子的颜色根据柱子的高度不同而变化。如果想要添加一个颜色标尺,可以使用以下代码:
1 2 3 4 5 6 7 8
| fig = plt.figure(figsize=(6, 5),dpi=300) ax = fig.add_subplot(111, projection='3d') ax.bar3d(x, y, z, dx, dy, dz, color=colors,shade=True) cbar = fig.colorbar(plt.cm.ScalarMappable(cmap = 'jet'), ax = ax,ticks=[0, 0.5, 1], pad=0.1) \\ ticks设定了标尺的标量刻度,0为最小刻度,1为满刻度,这里只显示三个刻度。 cbar.ax.set_yticklabels([round(dz.min(),2),round((dz.min()+dz.max())/2,2),round(dz.max(),2)]) \\设置刻度的显示值,分别为柱子高度的最低值,中间值和最大值。 plt.show()
|
4.可选的样式和格式 可以使用bar3d函数的其他参数来调整柱形图的样式和格式,例如:alpha、edgecolor、linewidth等。
5.如果图形颜色比较暗或者比较亮,可以使用lightsource参数调节光源的位置。
1 2 3
| lightsource = LightSource(azdeg=45) ax.bar3d(x, y, z, dx, dy, dz, color=colors,shade=True,lightsource=lightsource)
|
LightSource有几个参数,其中用到比较多的就是azdeg,这个值是光源从三维图俯视角度上看下去在图里的位置,默认为315°,表示,光源处在俯视图上,西北方向。正北方为0°,按顺时针方向角度增加。如果默认光源不合适,可以将azdeg设置为45°。
6.除了光源问题,还有柱子堆积方向的问题,由于x轴和y轴是固定从小到大排列,柱子高度可能会在y轴较小时比较大,导致矮的柱子被高的柱子遮挡,此时可以尝试反转轴排列方向,让y轴从大到小排列。
1 2 3
| ax.set_ylim(max(y),min(y)) \\y轴从大到小排列 ax.set_xlim(max(x),min(x)) \\x轴从大到小排列 ax.bar3d(x, y, z, dx, dy, dz, color=colors,shade=True,lightsource=lightsource)
|
7.柱子高度变化值相对于柱子高度值太小,比如dz在(666666,666699)之间。呈现出来的结果可能时,柱子高度几乎相同,但是颜色却变化很大。为了避免此问题,可以将柱子高度的范围缩小到(0,33)之间,而刻度值显示其真是大小。
1 2 3
| z = min(dz) dz=np.array(dz)-z ax.bar3d(x, y, z, dx, dy, dz, color=colors,shade=True,lightsource=lightsource)
|
z是柱子底面中心的坐标,原来全为0,现在改为柱子高度最小的值,dz为柱子的高度,现在改为原来的高度-高度最小值。那么每个柱子的高度,就是当前柱子与最短柱子的差。
这就是使用Matplotlib创建3D柱形图的基本步骤。通过调整数据和参数,可以创建出各种样式和格式的3D柱形图。
下面是我的数据绘制出的一个例子。