Search code examples
pythonmatplotlibgeometry-surface

Normalizing colors in matplotlib


I am trying to plot a surface using matplotlib using the code below:

from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import axes3d, Axes3D
import pylab as p

vima=0.5

fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(0, 16.67, vima)
Y = np.arange(0, 12.5, vima)
X, Y = np.meshgrid(X, Y)

Z = np.sqrt(((1.2*Y+0.6*X)**2+(0.2*Y+1.6*X)**2)/(0.64*Y**2+0.36*X**2))

surf = ax.plot_surface(X, Y, Z,rstride=1, cstride=1, alpha=1,cmap=cm.jet,  linewidth=0)
fig.colorbar(surf, shrink=0.5, aspect=5)

plt.show()

If you run it you will see a blue surface, but I want to use the whole color range of jet... I know there is a class "matplotlib.colors.Normalize", but I don't know how to use it. Could you please add the necessary code in order to do it?


Solution

  • As JoshAdel noted in a comment (credit belongs to him), it appears that the surface plot is improperly ranging the colormap when a NaN is in the Z array. A simple work-around is to simply convert the NaN's to zero or very large or very small numbers so that the colormap can be normalized to the z-axis range.

    from matplotlib import cm
    import matplotlib.pyplot as plt
    import numpy as np
    from mpl_toolkits.mplot3d import axes3d, Axes3D
    import pylab as p
    
    vima=0.5
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    X = np.arange(0, 16.67, vima)
    Y = np.arange(0, 12.5, vima)
    X, Y = np.meshgrid(X, Y)
    
    Z = np.sqrt(((1.2*Y+0.6*X)**2+(0.2*Y+1.6*X)**2)/(0.64*Y**2+0.36*X**2))
    Z = np.nan_to_num(Z) # added this line
    
    surf = ax.plot_surface(X, Y, Z,rstride=1, cstride=1, alpha=1,cmap=cm.jet,  linewidth=0)
    fig.colorbar(surf, shrink=0.5, aspect=5)
    
    plt.show()