0
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# create some sample data
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
z1 = np.array([1, 2, 3])
z2 = np.array([4, 5, 6])
z3 = np.array([7, 8, 9])
color1 = np.array(['r', 'g', 'b'])
color2 = np.array(['y', 'm', 'c'])

# create a figure and a set of subplots
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# plot the first set of bars
for i in range(len(x)):
    ax.bar(x[i], z1[i], y[i], zdir='y', color=color1[i], alpha=0.8)
    ax.bar(x[i], z1[i] - z1[i], y[i], zdir='y', color=color2[i], alpha=0.8)

# plot the second set of bars
for i in range(len(x)):
    ax.bar(x[i], z2[i], y[i]+0.5, zdir='y', color=color1[i], alpha=0.8)
    ax.bar(x[i], z2[i] - z2[i], y[i]+0.5, zdir='y', color=color2[i], alpha=0.8)

# plot the third set of bars
for i in range(len(x)):
    ax.bar(x[i], z3[i], y[i]+1.0, zdir='y', color=color1[i], alpha=0.8)
    ax.bar(x[i], z3[i] - z3[i], y[i]+1.0, zdir='y', color=color2[i], alpha=0.8)

# set the axis labels and title
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('3D Bar Chart')

# show the plot
plt.show()


Running this code in VSCode on Windows 11 (Python 3.10) results in the following error:

Traceback (most recent call last): File "c:\Users\16168\Documents\delta-scan-master\delta-scan-master\test\eval_test_display.py", line 73, in ax.bar(x[i], z1[i], y[i], zdir='y', color=color1[i], alpha=0.8) File "C:\Users\16168\Documents\delta-scan-master\delta-scan-master\env\lib\site-packages\matplotlib_init_.py", line 1459, in inner return func(ax, *map(sanitize_sequence, args), **kwargs) File "C:\Users\16168\Documents\delta-scan-master\delta-scan-master\env\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 2318, in bar zs = np.broadcast_to(zs, len(left)) TypeError: object of type 'numpy.int32' has no len()

I'm trying to create a set of 3d bar charts where each bar chart is bicolored (representing two different values along the vertical axis). I don't understand why the error is in line 73, rather than 72 where the len() function appears. I read the error as essentially saying that I'm calling the length function on an integer data type - but x is (should be?) a numpy array as declared above. Any ideas? Or is there a mismatch between the type of i and the type returned by len(x)?

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158

1 Answers1

0

Explanation with the first ax.bar() call but the error will be there for all the other ones.

for i in range(len(x)):
    ax.bar(x[i], z1[i], y[i], zdir='y', color=color1[i], alpha=0.8)

I don't understand why the error is in line 73, rather than 72 where the len() function appears.

The error is indeed not on the for i in range(len(x)) but on the ax.bar() call.

Axes3D.bar is expecting a list of x, y and z values, but you're passing single scalar values x[i], z[i] and y[i].

Instead of the for loop, you can directly pass the list of values (same for the color). It will create a bar for each i.

ax.bar(x, z1, y, zdir='y', color=color1, alpha=0.8)

Additional Notes:

  • This will create a 2D bar in a 3D axis. You want an actual 3D bar, use ax.bar3d
  • For each set of bars, in the second ax.bar call, you pass as second argument zX - zX which is probably wrong (0 height bar ; not visible).

Fixing the ax.bar() calls, this is what your figure looks like at the moment :

# [...]

# create a figure and a set of subplots
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# plot the first set of bars
ax.bar(x, z1, y, zdir='y', color=color1, alpha=0.8)
ax.bar(x, z1 - z1, y, zdir='y', color=color2, alpha=0.8)

# plot the second set of bars
ax.bar(x, z2, y+0.5, zdir='y', color=color1, alpha=0.8)
ax.bar(x, z2 - z2, y+0.5, zdir='y', color=color2, alpha=0.8)

# plot the third set of bars
ax.bar(x, z3, y + 1.0, zdir='y', color=color1, alpha=0.8)
ax.bar(x, z3 - z3, y + 1.0, zdir='y', color=color2, alpha=0.8)

# [...]

enter image description here

thmslmr
  • 1,251
  • 1
  • 5
  • 11