[英]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_under
和cmap.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.