繁体   English   中英

matplotlib中的离散然后线性色图

[英]Discrete then linear colormap in matplotlib

我的数据矩阵范围为0到102,使用imshow时,我希望将0显示为深红色,将1显示为黄绿色,其他所有值从2到102呈线性梯度变化,从标准绿色到绿色。深绿色。

到目前为止,我已经尝试使用颜色表“ Greens”并替换前两个值,但是结果不一致,而且我不知道如何仅使用颜色表的一半。 我也尝试过使用colordict生成自己的颜色图,然后覆盖前两个条目,但是根据提交的数据,结果也不一致(例如1显示为红色)

您可以使用make_colormap制作自定义颜色图:

mygreen = make_colormap([c('burnt red'), 
                         c('yellow green'), idx[1], c('yellow green'), 
                         (0,1,0), idx[2], (0,1,0),  # RGB (0,1,0) is standard green?
                         c('dark green')])
  • make_colormap的参数是RGB值和浮点数的序列。

  • 每个浮点都夹在两个RGB值之间。

  • 浮点数指示颜色图从一种RGB颜色过渡到另一种颜色的位置(范围从0.0到1.0)。

  • 序列中的第一个和最后一个值是颜色图中的第一个和最后一个颜色。


import numpy as np
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
np.random.seed(2016)

def make_colormap(seq):
    """Return a LinearSegmentedColormap
    seq: a sequence of floats and RGB-tuples. 
      - Every float is sandwiched between two RGB values.
      - The floats indicate locations (on a scale from 0.0 to 1.0) where the
        color map transitions from one RGB color to the next.
      - The floats should be in increasing order
      - The first and last values in the sequence are the first and last
        colors in the color map.
    https://stackoverflow.com/q/16834861/190597 (unutbu)
    """
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
    cdict = {'red': [], 'green': [], 'blue': []}
    for i, item in enumerate(seq):
        if isinstance(item, float):
            r1, g1, b1 = seq[i - 1]
            r2, g2, b2 = seq[i + 1]
            cdict['red'].append([item, r1, r2])
            cdict['green'].append([item, g1, g2])
            cdict['blue'].append([item, b1, b2])
    return mcolors.LinearSegmentedColormap('CustomMap', cdict)

# There are 103 integers from 0 to 102 (inclusive)
idx = np.linspace(0, 1, 103)
c = mcolors.ColorConverter().to_rgb
mygreen = make_colormap([c('burnt red'), 
                         c('yellow green'), idx[1], c('yellow green'), 
                         (0,1,0), idx[2], (0,1,0),  # RGB (0,1,0) is standard green?
                         c('dark green')])

arr = np.random.randint(0, 103, size=(11, 11))
print(np.where(arr==0))
print(np.where(arr==1))
plt.imshow(arr, interpolation='nearest', cmap=mygreen, vmin=0, vmax=102)
plt.colorbar(ticks=list(range(0, 100, 10))+[102])
plt.show()

在此处输入图片说明

另一个(可能更好)的选项是修改arr以利用matplotlib的cmap.set_undercmap.set_over方法。 这些颜色图方法使您可以为所有低于或超过指定限制的值设置颜色:

cmap = make_colormap([(0,1,0), c('dark green')])
cmap.set_under('burnt red')
cmap.set_over('yellow green')

因此,在特殊情况下,如果您只有两种特殊颜色,则可以修改arr以便将0映射为负数,将1映射为大于100的数字,然后将其余数字移动到range从0到100:

arr -= 2   
arr = np.where(arr==-1, 102, arr)

例如,

import numpy as np
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
np.random.seed(2016)

def make_colormap(seq):
    """Return a LinearSegmentedColormap
    seq: a sequence of floats and RGB-tuples. 
      - Every float is sandwiched between two RGB values.
      - The floats indicate locations (on a scale from 0.0 to 1.0) where the
        color map transitions from one RGB color to the next.
      - The floats should be in increasing order
      - The first and last values in the sequence are the first and last
        colors in color map.
    https://stackoverflow.com/q/16834861/190597 (unutbu)
    """
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
    cdict = {'red': [], 'green': [], 'blue': []}
    for i, item in enumerate(seq):
        if isinstance(item, float):
            r1, g1, b1 = seq[i - 1]
            r2, g2, b2 = seq[i + 1]
            cdict['red'].append([item, r1, r2])
            cdict['green'].append([item, g1, g2])
            cdict['blue'].append([item, b1, b2])
    return mcolors.LinearSegmentedColormap('CustomMap', cdict)

c = mcolors.ColorConverter().to_rgb
cmap = make_colormap([(0,1,0), c('dark green')])
cmap.set_under('burnt red')
cmap.set_over('yellow green')

arr = np.random.randint(0, 102, size=(11, 11))
# modify arr so that 0 is mapped to a negative number (-2) and 1 is mapped to a
# positive number greater than 100, (say, 102), and all other values are
# decreased by 2
arr -= 2   
arr = np.where(arr==-1, 102, arr)

plt.imshow(arr, interpolation='nearest', cmap=cmap, vmin=0, vmax=100)
plt.colorbar(extend='both')
plt.show()

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM