修正matplotlib colorbar ticks

时间:2013-09-09 18:11:04

标签: python matplotlib color-mapping

我在一个等值区域地图旁边放了一个颜色条。因为绘制的数据是离散的而不是连续的值,所以我使用了一个LinearSegmentedColormap(使用the recipe from the scipy cookbook),我用我的最大计数值+ 1初始化,以显示0的颜色。 ,我现在有两个问题:

enter image description here

  1. 刻度标签间距不正确(5或更多或更少) - 它们应位于它们识别的颜色的中间;即0 - 4应向上移动,6 - 10应向下移动。

  2. 如果我使用drawedges=True初始化颜色栏,以便我可以设置其dividers属性的样式,我就明白了:

  3. enter image description here

    我正在创建我的色彩映射和色条:

    cbmin, cbmax = min(counts), max(counts)
    # this normalises the counts to a 0,1 interval
    counts /= np.max(np.abs(counts), axis=0)
    # density is a discrete number, so we have to use a discrete color ramp/bar
    cm = cmap_discretize(plt.get_cmap('YlGnBu'), int(cbmax) + 1)
    mappable = plt.cm.ScalarMappable(cmap=cm)
    mappable.set_array(counts)
    # set min and max values for the colour bar ticks
    mappable.set_clim(cbmin, cbmax)
    pc = PatchCollection(patches, match_original=True)
    # impose our colour map onto the patch collection
    pc.set_facecolor(cm(counts))
    ax.add_collection(pc,)
    cb = plt.colorbar(mappable, drawedges=True)
    

    所以我想知道我将计数转换为0,1区间是否是其中一个问题。

    更新:

    在尝试了Hooked所建议的内容之后,0值是正确的,但随后的值逐渐设置得更高,到9应该是10的位置:

    enter image description here

    这是我使用的代码:

    cb = plt.colorbar(mappable)
    labels = np.arange(0, int(cbmax) + 1, 1)
    loc = labels + .5
    cb.set_ticks(loc)
    cb.set_ticklabels(labels)
    

    要确认,labels肯定有正确的值:

    In [3]: np.arange(0, int(cbmax) + 1, 1)
    Out[3]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
    

2 个答案:

答案 0 :(得分:18)

您正遭受一个错误的错误。你有11种颜色的10个滴答标签。您可以使用np.linspace代替np.arange来更正错误。使用np.linspace第三个参数是所需值的数量。这减少了避免一对一错误所需的心理体操的数量:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
import matplotlib.colors as mcolors

def colorbar_index(ncolors, cmap):
    cmap = cmap_discretize(cmap, ncolors)
    mappable = cm.ScalarMappable(cmap=cmap)
    mappable.set_array([])
    mappable.set_clim(-0.5, ncolors+0.5)
    colorbar = plt.colorbar(mappable)
    colorbar.set_ticks(np.linspace(0, ncolors, ncolors))
    colorbar.set_ticklabels(range(ncolors))

def cmap_discretize(cmap, N):
    """Return a discrete colormap from the continuous colormap cmap.

        cmap: colormap instance, eg. cm.jet. 
        N: number of colors.

    Example
        x = resize(arange(100), (5,100))
        djet = cmap_discretize(cm.jet, 5)
        imshow(x, cmap=djet)
    """

    if type(cmap) == str:
        cmap = plt.get_cmap(cmap)
    colors_i = np.concatenate((np.linspace(0, 1., N), (0.,0.,0.,0.)))
    colors_rgba = cmap(colors_i)
    indices = np.linspace(0, 1., N+1)
    cdict = {}
    for ki,key in enumerate(('red','green','blue')):
        cdict[key] = [ (indices[i], colors_rgba[i-1,ki], colors_rgba[i,ki])
                       for i in xrange(N+1) ]
    # Return colormap object.
    return mcolors.LinearSegmentedColormap(cmap.name + "_%d"%N, cdict, 1024)

fig, ax = plt.subplots()
A = np.random.random((10,10))*10
cmap = plt.get_cmap('YlGnBu')
ax.imshow(A, interpolation='nearest', cmap=cmap)
colorbar_index(ncolors=11, cmap=cmap)    
plt.show()

enter image description here

答案 1 :(得分:11)

您可以手动控制展示位置和标签。我将从the page you linkedcmap_discretize生成的线性cmap开始:

import numpy as np
import pylab as plt

# The number of divisions of the cmap we have
k = 10

# Random test data
A = np.random.random((10,10))*k
c = cmap_discretize('jet', k)

# First show without
plt.subplot(121)
plt.imshow(A,interpolation='nearest',cmap=c)
plt.colorbar()

# Now label properly
plt.subplot(122)
plt.imshow(A,interpolation='nearest',cmap=c)

cb = plt.colorbar()
labels = np.arange(0,k,1)
loc    = labels + .5
cb.set_ticks(loc)
cb.set_ticklabels(labels)

plt.show()

enter image description here