简体   繁体   English

在Matplotlib中设置与特定数据范围相对应的离散色彩图

[英]Setting discrete colormap corresponding to specific data range in Matplotlib

Some background 一些背景

I have a 2-d array in the shape of (50,50), the data value are range from -40 ~ 40. 我有一个形状为(50,50)的2维数组,数据值的范围是-40〜40。
But I want to plot the data in three data range[<0], [0,20], [>20] 但是我想在三个数据范围内绘制数据[<0],[0,20],[> 20]

Then, I need to generate a colormap corresponding to the three section. 然后,我需要生成与这三个部分相对应的颜色图。

I have some thought now 我现在想了

## ratio is the original 2-d array
binlabel = np.zeros_like(ratio)
binlabel[ratio<0] = 1
binlabel[(ratio>0)&(ratio<20)] = 2
binlabel[ratio>20] = 3

def discrete_cmap(N, base_cmap=None):
    base = plt.cm.get_cmap(base_cmap)
    color_list = base(np.linspace(0, 1, N))
    cmap_name = base.name + str(N)
    return base.from_list(cmap_name, color_list, N)

fig  = plt.figure()
ax = plt.gca()
plt.pcolormesh(binlabel, cmap = discrete_cmap(3, 'jet'))
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="4%", pad=0.45)
cbar = plt.colorbar(ratio_plot, cax=cax, orientation="horizontal")
labels = [1.35,2,2.65]
loc    = labels
cbar.set_ticks(loc)
cbar.ax.set_xticklabels(['< 0', '0~20', '>20']) 

Is there any better approach? 有没有更好的办法? Any advice would be appreciate. 任何建议,将不胜感激。

There are various answers to other questions using ListedColormap and BoundaryNorm , but here's an alternative. 使用ListedColormapBoundaryNorm对于其他问题有多种答案,但这是替代方法。 I've ignored the placement of your colorbar, as that's not relevant to your question. 我已经忽略了颜色栏的位置,因为这与您的问题无关。

You can replace your binlabel calculation with a call to np.digitize() and replace your discrete_cmap() function by using the lut argument to get_cmap() . 您可以使用对np.digitize()的调用来替换binlabel计算,并可以使用get_cmap()lut参数来替换您的binlabel discrete_cmap()函数。 Also, I find it easier to place the color bounds at .5 midpoints between the indexes rather than scale to awkward fractions of odd numbers: 另外,我发现将颜色范围放置在索引之间的.5中点处比将比例数缩放到奇数的尴尬分数更容易:

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

ratio = np.random.random((50,50)) * 50.0 - 20.0

fig2, ax2 = plt.subplots(figsize=(5,5))

# Turn the data into an array of N bin indexes (i.e., 0, 1 and 2).
bounds = [0,20]
iratio = np.digitize(ratio.flat,bounds).reshape(ratio.shape)

# Create a colormap containing N colors and a Normalizer that defines where 
# the boundaries of the colors should be relative to the indexes (i.e., -0.5, 
# 0.5, 1.5, 2.5).
cmap = cm.get_cmap("jet",lut=len(bounds)+1)
cmap_bounds = np.arange(len(bounds)+2) - 0.5
norm = mcol.BoundaryNorm(cmap_bounds,cmap.N)

# Plot using the colormap and the Normalizer.
ratio_plot = plt.pcolormesh(iratio,cmap=cmap,norm=norm)
cbar = plt.colorbar(ratio_plot,ticks=[0,1,2],orientation="horizontal")
cbar.set_ticklabels(["< 0","0~20",">20"])

离散色条示例

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

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