校正Matplotlib色条刻度 [英] Correcting matplotlib colorbar ticks

查看:366
本文介绍了校正Matplotlib色条刻度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在彩色地图旁边放置了一个彩条.因为要绘制的数据是离散的而不是连续的值,所以我使用了LinearSegmentedColormap(使用来自scipy食谱),我已将其最大计数值+ 1初始化,以显示0的颜色.但是,我现在有两个问题:

I've placed a color bar alongside a choropleth map. Because the data being plotted are discrete rather than continuous values, I've used a LinearSegmentedColormap (using the recipe from the scipy cookbook), which I've initialised with my max counted value + 1, in order to show a colour for 0. However, I now have two problems:

  1. 对勾标签的间距不正确(除了5个,或多或少)–它们应位于所标识颜色的中间;即0-4应该向上移动,6-10应该向下移动.

  1. The tick labels are incorrectly spaced (except for 5, more or less) – they should be located in the middle of the colour they identify; i.e. 0 - 4 should be moved up, and 6 - 10 should be moved down.

如果使用drawedges=True初始化颜色栏,以便可以设置其dividers属性的样式,则会得到以下信息:

If I initialise the colorbar with drawedges=True, so that I can style its dividers properties, I get this:

我正在创建自己的颜色图和颜色条,如下所示:

I'm creating my colormap and colorbar like so:

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间隔是否是问题之一.

So I'm wondering whether my converting the counts to a 0,1 interval is one of the problems.

尝试了Hooked的建议后,0值是正确的,但随后的值逐渐设置为更高,直至9等于10的值:

Having tried what Hooked suggested, the 0-value is correct, but subsequent values are set progressively higher, to the the point where 9 is where 10 should be:

这是我使用的代码:

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

为了确认,labels肯定具有正确的值:

And just to confirm, labels definitely has the correct values:

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

推荐答案

您正在遭受一个错误的错误.您有11种颜色之间的10个滴答标签.您可能可以通过使用np.linspace而不是np.arange来纠正错误.使用np.linspace,第三个参数是所需值的数量.这样可以减少为避免一次失误而需要进行的精神体操活动的次数:

You are suffering from an off-by-one error. You have 10 ticklabels spread among 11 colors. You might be able to correct the error by using np.linspace instead of np.arange. Using np.linspace the third argument is the number of values desired. This reduces the amount of mental gymnastics needed to avoid the off-by-one error:

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()

这篇关于校正Matplotlib色条刻度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆