Matplotlib离散的颜色条

我正在尝试为matplotlib中的scatterplot制作一个离散的颜色条

我有我的x,y数据,并为每个点一个整数标记值,我想用一个独特的颜色,例如

plt.scatter(x, y, c=tag) 

通常标签将是一个从0到20的整数,但确切的范围可能会改变

到目前为止,我只使用默认设置,例如

 plt.colorbar() 

这给出了连续的颜色范围。 理想情况下,我想要一组n个离散的颜色(在这个例子中n = 20)。 更好的办法是得到一个0的标签值产生一个灰色的颜色,1-20是丰富多彩的。

我find了一些“食谱”的脚本,但是它们非常复杂,我不认为它们是解决一个看似简单的问题的正确方法

您可以通过使用BoundaryNorm作为散点图的标准化程序,轻松创build自定义的离散色条。 古怪的位(在我的方法中)使0显示为灰色。

对于图像,我经常使用cmap.set_bad()并将我的数据转换为numpy蒙版数组。 这将是更容易使0灰色,但我不能得到这个分散或自定义的cmap工作。

作为替代scheme,您可以从头开始创build自己的cmap,或者读出现有的cmap,并覆盖一些特定的条目。

 # setup the plot fig, ax = plt.subplots(1,1, figsize=(6,6)) # define the data x = np.random.rand(20) y = np.random.rand(20) tag = np.random.randint(0,20,20) tag[10:12] = 0 # make sure there are some 0 values to showup as grey # define the colormap cmap = plt.cm.jet # extract all colors from the .jet map cmaplist = [cmap(i) for i in range(cmap.N)] # force the first color entry to be grey cmaplist[0] = (.5,.5,.5,1.0) # create the new map cmap = cmap.from_list('Custom cmap', cmaplist, cmap.N) # define the bins and normalize bounds = np.linspace(0,20,21) norm = mpl.colors.BoundaryNorm(bounds, cmap.N) # make the scatter scat = ax.scatter(x,y,c=tag,s=np.random.randint(100,500,20),cmap=cmap, norm=norm) # create a second axes for the colorbar ax2 = fig.add_axes([0.95, 0.1, 0.03, 0.8]) cb = mpl.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm, spacing='proportional', ticks=bounds, boundaries=bounds, format='%1i') ax.set_title('Well defined discrete colors') ax2.set_ylabel('Very custom cbar [-]', size=12) 

在这里输入图像描述

我个人认为有20种不同的颜色,有点难以读懂具体的价值,但那当然是你自己决定的。

你可以按照这个例子 :

 #!/usr/bin/env python """ Use a pcolor or imshow with a custom colormap to make a contour plot. Since this example was initially written, a proper contour routine was added to matplotlib - see contour_demo.py and http://matplotlib.sf.net/matplotlib.pylab.html#-contour. """ from pylab import * delta = 0.01 x = arange(-3.0, 3.0, delta) y = arange(-3.0, 3.0, delta) X,Y = meshgrid(x, y) Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = Z2 - Z1 # difference of Gaussians cmap = cm.get_cmap('PiYG', 11) # 11 discrete colors im = imshow(Z, cmap=cmap, interpolation='bilinear', vmax=abs(Z).max(), vmin=-abs(Z).max()) axis('off') colorbar() show() 

这会产生下面的图像:

poormans_contour

要设置高于或低于set_over图范围的值,您需要使用set_over映射的set_overset_under方法。 如果你想标记一个特定的值,掩盖它(即创build一个蒙面数组),并使用set_bad方法。 (查看基础颜色映射类的文档: http : //matplotlib.org/api/colors_api.html#matplotlib.colors.Colormap )

这听起来像你想要这样的事情:

 import matplotlib.pyplot as plt import numpy as np # Generate some data x, y, z = np.random.random((3, 30)) z = z * 20 + 0.1 # Set some values in z to 0... z[:5] = 0 cmap = plt.get_cmap('jet', 20) cmap.set_under('gray') fig, ax = plt.subplots() cax = ax.scatter(x, y, c=z, s=100, cmap=cmap, vmin=0.1, vmax=z.max()) fig.colorbar(cax, extend='min') plt.show() 

在这里输入图像描述

上面的答案是好的,除了在颜色条上没有适当的勾号。 我喜欢在颜色的中间有滴答,以便数字 – >颜色映射更清晰。 你可以通过改变matshow的限制来解决这个问题:

 import matplotlib.pyplot as plt import numpy as np def discrete_matshow(data): #get discrete colormap cmap = plt.get_cmap('RdBu', np.max(data)-np.min(data)+1) # set limits .5 outside true range mat = plt.matshow(data,cmap=cmap,vmin = np.min(data)-.5, vmax = np.max(data)+.5) #tell the colorbar to tick at integers cax = plt.colorbar(mat, ticks=np.arange(np.min(data),np.max(data)+1)) #generate data a=np.random.randint(1, 9, size=(10, 10)) discrete_matshow(a) 

离散的颜色条的例子

我想你会想看看colors.ListedColormap来生成你的色彩地图 ,或者如果你只需要一个静态的色彩地图 ,我一直在一个可能有帮助的应用程序工作。