2

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!

mzm
  • 373
  • 1
  • 6
  • 16

2 Answers2

2

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()

Figure with the 3-D bar chart

LDioica
  • 21
  • 3
1

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()

enter image description here

xnx
  • 24,509
  • 11
  • 70
  • 109