pythonmatplotlibscatter-plotscatter3d

In what order is meshgrid defined in scatter plot


I have already asked a similar question here and have almost figured out the answer by myself. The only thing that remains is the following: I am using meshgrid to create a 3D grid. When specifying the colors in color_map.set_array(colo) I am using an array which has the same size as elements in the meshgrid. But how does this array have to be ordered to yield the correct plot?

x=[7, 8, 9, 10, 11, 12]

y=  [0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

z= [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]

colo=np.random.normal(0, 1, 216)

X,Y,Z = np.meshgrid(x,y,z)

fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')

color_map = cm.ScalarMappable(cmap=cm.Greens_r)
color_map.set_array(colo)

img = ax.scatter(X, Y, Z, marker='s',
                 s=200, color='green')
plt.colorbar(color_map)


Solution

  • Suppose the lengths of y, x and z are 6, 5, and 4 (I'm giving each axis a unique length in order to easily distinguish between them). The size of each meshgrid (X, Y, and Z) from np.meshgrid(x, y, z) will be 6x5x4. That means your data needs to be structured in the format (y, x, z). Otherwise, the data won't line up with the arrangement of the meshgrid. You don't need to flatten the data.

    If the data isn't in the format of (y, x, z), rearrange it into that format. Then, you can give it to the colour parameter (c=) in ax.scatter as follows:

    import matplotlib.pyplot as plt
    from matplotlib import cm
    import numpy as np
    
    #Make some test data
    y = [0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
    x = [7, 8, 9, 10, 11]
    z = [0.1, 0.2, 0.3, 0.4]
    #Original data needs to be structured as (y, x, z)
    original_data = np.random.normal(0, 1, 120).reshape((6, 5, 4))
    
    X, Y, Z = np.meshgrid(x, y ,z)
    
    ax = plt.figure(figsize=(10, 10)).add_subplot(111, projection='3d')
    
    img = ax.scatter(X, Y, Z, marker='s', s=200, c=original_data, cmap=cm.Greens_r)
    ax.set(xlabel='x', ylabel='y', zlabel='z')
    plt.colorbar(img)
    

    enter image description here