Reputation: 937
I am creating a scatterplot with a colorbar
plt.scatter(X, Y, c=Z)
plt.colorbar()
plt.show()
plt.close()
where X and Y are float arrays and Z is an integer array.
Even though Z is an integer array (here 1-14), the colorbar displays floats.
How can I display a discrete colorbar 1-14?
I found something attempting to answer a similar question here, but I don't understand the answer (containing some complications to make 0 be gray) well enough to apply it.
Upvotes: 4
Views: 8831
Reputation: 3852
Here is my discrete colorbar for land use type, it seems like your work,because the Z value is also an interger array from 1-14.
creat the colormap and colorbar label manually learned from here
cMap = ListedColormap(['white', '#8dd3c7','#ffffb3','#bebada', \
'#b2182b','#80b1d3','#fdb462','#b3de69','#6a3d9a',\
'#b2df8a', '#1f78b4', '#ccebc5','#ffed6f'])
## If you want to use the colormap from plt.cm..., you can use(take 'jet' for example)
cMap = plt.cm.get_cmap("jet",lut=13)
### here you can change your data in
lulc = plt.pcolormesh(lulc,cmap = cMap,alpha = 0.7)
z_range = np.linspace(1,14,14)
list = z_range.astype('S10')
k = -0.05
for i in range(0,13,1):
k = k + 1/13.0
ax.annotate(list[i],xycoords='axes fraction',xy=(1.12,k),fontsize = 14, \
fontstyle = 'italic',zorder =3)
cbar = plt.colorbar(lulc,ticks = [ ])
for label in cbar.ax.yaxis.get_ticklabels()[::-1]:
label.set_visible(False)
(source: tietuku.com)
Wish it can help!
Upvotes: 0
Reputation: 35125
Check out the second answer to your linked question. If you discretize your colourmap before calling scatter
, it will automatically work as you want it to:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
n = 14
X = np.random.rand(20)
Y = np.random.rand(20)
Z = np.random.randint(low=0,high=n,size=X.shape)
plt.figure()
plt.scatter(X,Y,c=Z,cmap=cm.hot)
plt.colorbar()
plt.figure()
plt.scatter(X,Y,c=Z,cmap=cm.get_cmap('hot',n))
plt.colorbar()
Results for comparison:
Note that the default colourmap is jet
. But only until viridis
kicks in starting from version 2.0 as the new (and wonderful) default.
If what's bothering you is that the numbers are floating-point on the colourbar, you can set manual ticks
in it, irrespective of the discretization of colours:
plt.figure()
plt.scatter(X,Y,c=Z,cmap=cm.jet)
plt.colorbar(ticks=np.unique(Z))
#or
#plt.colorbar(ticks=range(Z.min(),Z.max()+1))
Result:
Note that since I used a few random-generated points, not every number is present in Z
, so unique
might not be the best approach (see the missing ticks in the above figure). This is why I also added a solution based on min/max
. You can tailor the limits to your needs depending on your actual application.
Upvotes: 4