0

I want to give different gradient colour for z i.e Numeric variable in my 3D Bar Graph on the basis of some cut of value or gradient for lowest to highest value.I want to put condition say if dz is >=50 then green colour bar else red colour ba. Attached the code, Please share if there's any solution for this.

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

fig = plt.figure()
ax = fig.add_subplot(111, projection = "3d")

ax.set_xlabel("Cumulative HH's")
ax.set_ylabel("Index") 
ax.set_zlabel("# Observations")

xpos = [1,2,3,4,5,6,7,8,9,10,11,12]#
ypos = [2,4,6,8,10,12,14,16,18,20,22,24]#
zpos = np.zeros(12)

dx = np.ones(12)
dy = np.ones(12)
dz = [100,3,47,35,8,59,24,19,89,60,11,25]
colors=['pink']
ax.bar3d(xpos,ypos,zpos,dx,dy,dz,color=colors)

enter image description here

1 Answers1

2

The color= parameter to bar3d can be a list of colors with one entry per bar. Such a list can be built using a colormap.

Here is an example that colors the bars using a smooth range from green for the highest and red for the lowest. Changing the colormap to cmap = plt.cm.get_cmap('RdYlGn', 2) would color all the bars higher than the mean in green and the rest in red. To set the split condition exactly at 50, you can change the norm to norm = mcolors.Normalize(0, 100).

If only a few different colors are needed, the easiest is to forget about cmap and norm and just use:

colors = ['limegreen' if u > 50 else 'crimson' for u in dz]

Here is a complete example:

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

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")

ax.set_xlabel("Cumulative HH's")
ax.set_ylabel("Index")
ax.set_zlabel("# Observations")

xpos = np.arange(1, 13)
ypos = np.arange(2, 26, 2)
zpos = np.zeros(12)

dx = np.ones(12)
dy = np.ones(12)
dz = [100, 3, 47, 35, 8, 59, 24, 19, 89, 60, 11, 25]
cmap = plt.cm.get_cmap('RdYlGn')
norm = mcolors.Normalize(min(dz), max(dz))
colors = [cmap(norm(u)) for u in dz]
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color=colors)

plt.show()

At the left an example with a range of colors, at the right an example with only 2 colors:

example plot

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • hi @JohanC Thank you for the solution, it did work but can you please suggest me instead of normalizing the variable if I want to add Condition( eg. wherever observation is greater than 50, I want that in green colour else red colour bar) – Anamta sayyed Feb 21 '20 at 12:42
  • To set the condition exactly at 50, you can use `norm = mcolors.Normalize(0, 100)` – JohanC Feb 21 '20 at 12:44
  • and if the data range is 111-1112 and I would want to make a cut at 650 then? – Anamta sayyed Feb 21 '20 at 12:55
  • colors = ['limegreen' if u > 650 else 'crimson' for u in dz] – JohanC Feb 21 '20 at 12:56