Search code examples
python3dcontour

3d contour with 3 variables and 1 variable as colour


I have three variables for my plot and I colour by the fourth variable. I have made a scatter plot via the following code, but I want a contour plot. My code:

import numpy as np
import matplotlib.pyplot as plt

a=np.linspace(4.0,14.0,3)
b=np.linspace(0.5,2.5,3)
c=np.linspace(0.0,1.0,3)
d=np.random.rand(len(a),len(b),len(c))  #colour by this variable

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
z,y,x=np.meshgrid(c,a,b)
img = ax.scatter(x, y, z, c=d, cmap='RdGy')
fig.colorbar(img, pad=0.2).set_label('colour')
ax.set_xlabel('c')
ax.set_ylabel('a')
ax.set_zlabel('b')

plot I want a filled contour instead of scatter plot. I know mayavi.mlab has this feature, but I cannot import mlab for some reason. Is there an alternative, or is there a better way of presenting this data?


Solution

  • Here is how I would present this 3-dimensional data. Each plot is a cross-section through the cube. This makes sense intuitively.

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.linspace(4.0, 14.0, 3)
    y = np.linspace(0.5, 2.5, 3)
    z = np.linspace(0.0, 1.0, 3)
    data = np.random.rand(len(x), len(y), len(z))
    
    fig, axes = plt.subplots(len(z), 1, figsize=(3.5, 9), 
                             sharex=True,sharey=True)
    for i, (ax, d) in enumerate(zip(axes, data.swapaxes(0, 2))):
        ax.contour(x, y, d)
        ax.set_ylabel('y')
        ax.grid()
        ax.set_title(f"z = {z[i]}")
    axes[-1].set_xlabel('x')
    plt.tight_layout()
    plt.show()
    

    3 subplots showing contours

    My advice: 3D plots are rarely used for serious data visualization. While they look cool, it is virtually impossible to read any data points with any accuracy.

    Same thing goes for colours. I recommend labelling the contours rather than using a colour map.

    You can always use a filled contour plot to add colours as well.