diffracteD
diffracteD

Reputation: 758

generating custom colorbar: match data with color scheme

I have a 3D bar chart, generated from 3D discrete-dataset(x,y,z).
Used this code to plot on canvas:

bar_chart_3d =fx.bar3d(x, y, z, dx, dy, dz, color=cmap.to_rgba(dz), alpha=0.4,linewidth=0.5)  

But, I'm not being able to attach the colormap on the canvas based on which dz value is plotted.
Tried using:

#Adding a color-bar...
fig.colorbar(cmap.to_rgba(dz), shrink=0.6, aspect=8)   

But this is invoking AttributeError: 'numpy.ndarray' object has no attribute 'autoscale_None'.
Thank you.

Upvotes: 1

Views: 1227

Answers (1)

Ed Smith
Ed Smith

Reputation: 13206

From the bar3d docs, the color applied is to each face,

color can be:

An array of colors of length N bars, to color each bar independently.

I guess as this is just a facecolor, it is not assumed to convey information and the bar3d does not return anything. Things like contour return a ScalarMappable which can be used to specify the colorbar. It looks like your cmap (which I assume is a cm.ScalarMappable?) doesn't contain norm and autoscale required for colorbar.

As a work around you can draw the colorbar yourself between certain limits as in this example

fig.subplots_adjust(bottom=0.25)
ax1 = fig.add_axes([0.05, 0.10, 0.9, 0.1])
norm = mpl.colors.Normalize(vmin=dz.min(), vmax=dz.max())
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=mpl.cm.cool,
                               norm=norm,
                               orientation='horizontal')

where you minimum and maximum for dz specify a range which is consistent with your data.

EDIT: added a minimum working example where you specify a colormap, use it to get bar colors and add this colormap to the bottom.

from mpl_toolkits.mplot3d import Axes3D
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x, y = np.random.rand(2, 100) * 4
hist, xedges, yedges = np.histogram2d(x, y, bins=4)

elements = (len(xedges) - 1) * (len(yedges) - 1)
xpos, ypos = np.meshgrid(xedges[:-1]+0.25, yedges[:-1]+0.25)

xpos = xpos.flatten()
ypos = ypos.flatten()
zpos = np.zeros(elements)
dx = 0.5 * np.ones_like(zpos)
dy = dx.copy()
dz = hist.flatten()

#Define colormap and get values for barcolors from it
cmap = plt.cm.RdYlBu_r
norm = mpl.colors.Normalize(vmin=dz.min(), vmax=dz.max())
barcolors = plt.cm.ScalarMappable(norm, cmap)

#Plot bar3d
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color=barcolors.to_rgba(dz),alpha=0.4,linewidth=0.5, zsort='average')

#Add colorbar
fig.subplots_adjust(bottom=0.25)
ax1 = fig.add_axes([0.05, 0.10, 0.9, 0.1])
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cmap,
                                   norm=norm,
                                   orientation='horizontal')
plt.show()

Which gives, enter image description here

Upvotes: 2

Related Questions