Search code examples
pythonmatplotliblegendcolorbarcolormap

LEGEND in a 3D bar plot as a colormap


I have a 3D bar plot in matplotlib which consists of a total 40 bars and at the moment it is quite confusing.I converted my data array to an array of colors using a colormap. colors = plt.cm.jet(data.flatten()/float(data.max()))

Now i need to Plot the Legend of this colour map. [Sort of color scale on how the colors are related to the values.]

import os
import glob
import shutil
import pandas as pd
import plotly.express as px
import xlrd
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

#%matplotlib nbagg
x=np.array(range(0,4),float)
y=np.array(range(0,10),float)
xpos,ypos = np.meshgrid(x,y)
z=np.random.rand(4,10)
z=np.array([[1434.273,1437.1749,1441.878,1441.155],
           [1392.140,1371.859,1384.381,1309.88],
           [1333.66,1283.08,1220.85,1268.912],
           [1538.289,1327.628,1278.87,1372.7348],
           [1393.3608,1321.353,1276.506,1248.3100],
           [1394.632,1340.46,1286.30,1346.60],
           [1352.29,1324.48,1229.475,1276.067],
           [1345.233,1285.63,1265.30,1335.97],
           [1406.068,1411.614,1320.27,1390.042],
           [1396.901,1430.822,1455.797,1476.244]])

xpos=xpos.flatten()
ypos=ypos.flatten()
zpos=np.zeros_like(xpos)

dx=0.5*np.ones_like(xpos)
dy=dx.copy()
dz=z.flatten()

fig=plt.figure(figsize = (11,8))
ax=fig.add_subplot(111, projection = "3d")
label = ["E"]

ax.set_title("Variation of Average E along 40 Print positions", fontsize = 25)
ax.set_xticks(range(4))
ax.set_xticklabels(["A", "B", "C", "D"])
ax.set_xlabel("Probe Numbers on X plane",labelpad=15)

ax.set_yticklabels([1,2,3,4,5,6,7,8,9,10])
ax.set_yticks(range(10))
ax.set_ylabel("Probe Numbers on Y plane",labelpad=15)

ax.set_zlabel("E", labelpad=15)
colors = plt.cm.jet(z.flatten()/float(z.max()))

ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color= colors)

#plt.imshow(mat, origin="lower", cmap='gray', interpolation='nearest')

#ax.legend([colors],label)
plt.show()

enter image description here


Solution

  • Check this code:

    import os
    import glob
    import shutil
    import pandas as pd
    import plotly.express as px
    import xlrd
    import matplotlib.pyplot as plt
    # %matplotlib inline
    import numpy as np
    from mpl_toolkits.mplot3d import Axes3D
    import numpy as np
    
    #%matplotlib nbagg
    x=np.array(range(0,4),float)
    y=np.array(range(0,10),float)
    xpos,ypos = np.meshgrid(x,y)
    # z=np.random.rand(4,10)
    z=np.array([[1434.273,1437.1749,1441.878,1441.155],
               [1392.140,1371.859,1384.381,1309.88],
               [1333.66,1283.08,1220.85,1268.912],
               [1538.289,1327.628,1278.87,1372.7348],
               [1393.3608,1321.353,1276.506,1248.3100],
               [1394.632,1340.46,1286.30,1346.60],
               [1352.29,1324.48,1229.475,1276.067],
               [1345.233,1285.63,1265.30,1335.97],
               [1406.068,1411.614,1320.27,1390.042],
               [1396.901,1430.822,1455.797,1476.244]])
    
    xpos=xpos.flatten()
    ypos=ypos.flatten()
    zpos=np.zeros_like(xpos)
    
    dx=0.5*np.ones_like(xpos)
    dy=dx.copy()
    dz=z.flatten()
    
    fig=plt.figure(figsize = (11,8))
    ax=fig.add_subplot(111, projection = "3d")
    label = ["E"]
    
    ax.set_title("Variation of Average E along 40 Print positions", fontsize = 25)
    ax.set_xticks(range(4))
    ax.set_xticklabels(["A", "B", "C", "D"])
    ax.set_xlabel("Probe Numbers on X plane",labelpad=15)
    
    ax.set_yticklabels([1,2,3,4,5,6,7,8,9,10])
    ax.set_yticks(range(10))
    ax.set_ylabel("Probe Numbers on Y plane",labelpad=15)
    
    ax.set_zlabel("E", labelpad=15)
    colors = plt.cm.jet((z.flatten() - z.min()) / (z.max() - z.min()))
    
    bar = ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color= colors)
    
    #plt.imshow(mat, origin="lower", cmap='gray', interpolation='nearest')
    
    fig.colorbar(plt.cm.ScalarMappable(cmap = 'jet'), ax = ax)
    plt.show()
    

    In order to show the colorbar, I added:

    fig.colorbar(plt.cm.ScalarMappable(cmap = 'jet'), ax = ax)
    

    Then, I edit this line of your code:

    colors = plt.cm.jet((z.flatten() - z.min()) / (z.max() - z.min()))
    

    in this way colors goes from 0 to 1 (it is correctly normalized), so you can use all the colorbar range.
    This is the result:

    enter image description here