I am looking to make a 3D bar chart plot, as shown here or here, but with stacked bars, as seen here.
Anyone have an idea how to do these two in the same plot?
Thanks!
You can also do it with bar3d: the zpos parameter allows you to set the bottom of the bars. Here an example based on demo code from matplotlib examples (hist3d_demo.py)
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x, y = np.random.rand(2, 100) * 4
hist, xedges, yedges = np.histogram2d(x, y, bins=4, range=[[0, 4], [0, 4]])
# Construct arrays for the anchor positions of the 16 bars.
# Note: np.meshgrid gives arrays in (ny, nx) so we use 'F' to flatten xpos,
# ypos in column-major order. For numpy >= 1.7, we could instead call meshgrid
# with indexing='ij'.
xpos, ypos = np.meshgrid(xedges[:-1] + 0.25, yedges[:-1] + 0.25)
xpos = xpos.flatten('F')
ypos = ypos.flatten('F')
# z position set to zero
zpos = np.zeros_like(xpos)
# Construct arrays with the dimensions for the 16 bars.
dx = 0.5 * np.ones_like(zpos)
dy = dx.copy()
dz = hist.flatten()
# Create a random second histogram
dz2 = dz * np.random.rand(16)
# Set z position to the values of the first histogram
zpos2 = dz
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average', alpha=0.7)
ax.bar3d(xpos, ypos, zpos2, dx, dy, dz2, color='r', zsort='average', alpha=0.7)
plt.show()
You can set bottom
in a 3-D bar chart, just the same as 2-D:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
colors = ['r', 'g', 'b', 'y']
for i, (c, z) in enumerate(zip(colors, [30, 20, 10, 0])):
xs = np.arange(20)
ys = np.random.rand(20)
ys2 = np.random.rand(20)
ys3 = 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)
ax.bar(xs, ys2, bottom=ys, zs=z, zdir='y', color=colors[(i+1)%4], alpha=0.8)
ax.bar(xs, ys3, bottom=ys+ys2, zs=z, zdir='y', color=colors[(i+2)%4], alpha=0.8)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()