weird behavior with 3d histogram in matplotlib in Python
I have an Nx3 matrix in scipy/numpy and I'd like to make a 3 dimensional bar graph out of it, where the X and Y axes are determined by the values of first and second columns of the matrix, the height of each bar is the third column in the matrix, and the number of bars is determined by N.
Furthermore, I want to plot several groups of these matrices, each in a different color (a "grouped" 3D bar plot.)
When I try to plot it as follows:
ax.bar(data开发者_StackOverflow中文版[:, 0], data[:, 1], zs=data[:, 2],
zdir='z', alpha=0.8, color=curr_color)
I get really weird bars -- as seen here: http://tinypic.com/r/anknzk/7
Any idea why the bars are so crooked and weirdly shaped? I just want one bar at the X-Y point, whose height is equal to the Z point.
You aren't using the keyword argument zs
correctly. It refers to the planes at which each set of bars is placed (defined along the axis zdir
). They are crooked because it makes the assumption that a set of bars defined by a ax.bar
call are in the same plane. You are probably better off calling ax.bar
multiple times (one for each plane). Follow this example closely. You will want zdir
to be either 'x'
or 'y'
.
Edit
Here is the full code (based heavily on the example linked above).
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')
# this is just some setup to get the data
r = numpy.arange(5)
x1,y1 = numpy.meshgrid(r,r)
z1 = numpy.random.random(x1.shape)
# this is what your data probably looks like (1D arrays):
x,y,z = (a.flatten() for a in (x1,y1,z1))
# preferrably you would have it in the 2D array format
# but if the 1D is what you must work with:
# x is: array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4,
# 0, 1, 2, 3, 4, 0, 1, 2, 3, 4,
# 0, 1, 2, 3, 4])
# y is: array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
# 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
# 4, 4, 4, 4, 4])
for i in range(0,25,5):
# iterate over layers
# (groups of same y)
xs = x[i:i+5] # slice each layer
ys = y[i:i+5]
zs = z[i:i+5]
layer = ys[0] # since in this case they are all equal.
cs = numpy.random.random(3) # let's pick a random color for each layer
ax.bar(xs, zs, zs=layer, zdir='y', color=cs, alpha=0.8)
plt.show()
精彩评论