Reputation: 31
I have a 3D array sized (100,519,492). I want to plot a 3D heat map, where color is defined by the array values and the locations are defined by the index in the array. I have tried googling around and I haven't come anywhere near close to getting a result.
I essentially want to plot this 2D data set 100 times, forming areas that are colored in based on the array value (in this case the value was set to be either 0-white or red-1):
I have tried following this guide: https://www.geeksforgeeks.org/3d-heatmap-in-python/, but I get
ValueError: shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 0 with shape (492,) and arg 1 with shape (519,).
# importing required libraries
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from pylab import *
x = np.arange(0,492) #Number of columns in my 3d data array
y = np.arange(0,519) # Number of rows
z = np.arange(0,100) # Number of 2D slices making the 3D array
colo = ODS_diff # ODS_diff is the 3D array
# creating figures
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
# setting color bar
color_map = cm.ScalarMappable(cmap=cm.Greens_r)
color_map.set_array(colo)
# creating the heatmap
ax.scatter(x, y, z, marker='s',
s=200, color='red')
plt.colorbar(colo)
# adding title and labels
ax.set_title("3D Heatmap")
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')
# displaying plot
plt.show()
Upvotes: 3
Views: 6320
Reputation: 25043
You are (or rather your reference is) overcomplicating
import matplotlib.pyplot as plt
import numpy as np
# different from yours, see below
x = y = z = np.linspace(-2, 2, 41)
X, Y, Z = np.meshgrid(x, y, z)
values = 2*X*X - Y*Y + 1/(Z*Z+1)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
scatter = ax.scatter(X, Y, Z, c=values, cmap='PRGn')
fig.colorbar(scatter, ax=ax)
plt.show()
That said ("It's easy if you ask the right guys") I have to make a remark about
x = np.arange(0,492) #Number of columns in my 3d data array
y = np.arange(0,519) # Number of rows
z = np.arange(0,100) # Number of 2D slices making the 3D array
With a grid with shape (41, 41, 41)
the density of the points/spheres is already too much, and it takes a couple of seconds to render in the first place, and even more when I try to rotate or zoom. Imagine what happens when in place of ~64000 points you want to represent ~25 million points.
It is possible that you want to sample a subset of your grid.
Upvotes: 4