13

i worked on a simple 3d bar chart using the following code:

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

ax.set_xlabel("x")
ax.set_ylabel("y") 
ax.set_zlabel("z")
ax.set_xlim3d(0,10)
ax.set_ylim3d(0,10) 
ax.set_zlim3d(0,2)

xpos = [2,5,8,2,5,8,2,5,8]
ypos = [1,1,1,5,5,5,9,9,9]
zpos = np.zeros(9)

dx = np.ones(9)
dy = np.ones(9)
dz = np.ones(9)

ax.bar3d(xpos, ypos, zpos, dx, dy, dz)
plt.gca().invert_xaxis()
plt.show()

Thinking of this just as a test, all seems to be clear so far. I just wondered how i can plot each of these 9 bars in a stacked way, so that e.g. each bar is divided in 4 parts that make up the whole bar.

Basically, im thinking of doing this in the way of the example here.

But instead of 2 stacks, i want to have 4. Any ideas how to proceed from the point i am now? Each hint would be so much appreciated.

Thanks!

edit: if i want to implement given values for each stacked bar, e.g:

...
z = [np.array([ 0.2, 0.6, 0.3, 0.6, 0.4, 0.3, 0.8, 0.5,  0.7]), 
     np.array([ 0.8, 0.4, 0.5, 0.2, 0.8, 0.7, 0.4, 0.2,  0.9]),
     np.array([ 0.1, 0.2, 0.4, 0.4, 0.2, 0.6, 0.3, 0.6,  0.9]),
     np.array([ 0.9, 0.5, 0.7, 0.2, 0.5, 0.6, 0.7, 0.9,  0.7])]
dz = [z for i in range(4)]
...

this doesnt seem to work and i dont know why?

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Alex
  • 337
  • 4
  • 12
  • 1
    I did something similar [here](http://stackoverflow.com/questions/35246780/is-it-possible-to-superimpose-3-d-bar-charts-in-matplotlib/35248519#35248519), but you will probably run into difficulties with matplotlib's way of plotting depth information. My answer should be applicable to your problem though, only you have to change the `zpos` rather than the color/opacity of the bar plots. – Andras Deak -- Слава Україні Jun 28 '16 at 22:23

1 Answers1

18

To make a stacked 3d bar plot, you can accumulate your dz values and use them as the base for each next bar. Here's an example:

enter image description here

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

ax.set_xlabel("x")
ax.set_ylabel("y") 
ax.set_zlabel("z")
ax.set_xlim3d(0,10)
ax.set_ylim3d(0,10) 

xpos = [2,5,8,2,5,8,2,5,8]
ypos = [1,1,1,5,5,5,9,9,9]
zpos = np.zeros(9)

dx = np.ones(9)
dy = np.ones(9)
dz = [np.random.random(9) for i in range(4)]  # the heights of the 4 bar sets

_zpos = zpos   # the starting zpos for each bar
colors = ['r', 'b', 'g', 'y']
for i in range(4):
    ax.bar3d(xpos, ypos, _zpos, dx, dy, dz[i], color=colors[i])
    _zpos += dz[i]    # add the height of each bar to know where to start the next

plt.gca().invert_xaxis()
plt.show()
tom10
  • 67,082
  • 10
  • 127
  • 137
  • this looks very good, indeed. matches the way i imagined that, thx so far! if i have values for each stack (and color), e.g. my first bar consists of the values v = [0.5,0.2,0.6,0.9] - and these values vary from bar to bar: how do i inplement them in my variable dz? – Alex Jun 29 '16 at 02:17
  • As I have it set up, dz is a list of 4 arrays, and the elements in each array are the heights for a single level of all of the bars (eg, the first array is all the red bars, the next is all the blue bars, etc). I just did this to match your program outline though. Overall, if you have a data structure you want to use, it's helpful to give that in the question statement as these things are hard to work out in the comments. – tom10 Jun 29 '16 at 02:21
  • i added an example for my data in the original question. maybe you can help me? – Alex Jul 06 '16 at 21:14