在带有离散颜色条的pcolormesh图中使用extend

时间:2018-02-04 23:09:48

标签: python matplotlib plot colorbar colormap

我正在尝试创建一个带有离散颜色条的pcolormesh图。输出应符合以下标准:

  1. 第一级应为白色
  2. 数据应该在某个级别切断
  3. 截止上方的数据应该有一个单独的颜色(即色图的最后一种颜色)
  4. 我几乎就在那里,但'extend'关键字的行为与我预期的不同(“最大箭头”中的颜色与最后一个级别相同 - 参见示例)。 如何将'vmax'以上的值设置为单独的颜色(即我使用的任何色彩映射的最后颜色)

    import numpy as np
    import xarray as xr
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    ds = xr.Dataset(
        coords={'lon': np.arange(-180, 180, 10),
                'lat': np.arange(-85, 90, 10)},
        data_vars={'data': (('lat', 'lon'), np.random.rand(18, 36))})
    
    cmap = plt.cm.get_cmap('Reds')
    cmap.set_under('w')
    # cmap.set_over()  # do something here?
    levels = np.arange(0, .7, .1)
    ds.data.plot.pcolormesh(
        cmap=cmap,
        vmin=levels[1],
        # vmax=levels[-1],
        extend='max',
        norm = mpl.colors.BoundaryNorm(levels, ncolors=cmap.N, clip=False)
    )
    

    enter image description here

    我正在使用xarray,但plt.pcolormesh的行为是相同的:

    p = plt.pcolormesh(
        np.arange(-180, 180, 10),
        np.arange(-85, 90, 10),
        np.random.rand(18, 36),
        cmap=cmap,
        vmin=levels[1],
        # vmax=levels[-1],
        norm = mpl.colors.BoundaryNorm(levels, ncolors=cmap.N, clip=False)
    )
    plt.colorbar(p, extend='max') 
    

1 个答案:

答案 0 :(得分:4)

的确,如果设置cmap.set_over("blue"),您会看到蓝色,因为值的颜色超过了最大值。

enter image description here

但是,如果要将色彩映射的最后一种颜色用作set_over的颜色,则需要制作一个色彩映射,该色彩映射以最后一种颜色停止。为此,可以使用以下基本原理。如果我们针对色彩图中的6种不同颜色加上过冲值的颜色,我们从该色彩图中选取7种颜色,将第一种颜色替换为白色,并使用前6种颜色作为边界间隔的颜色。然后将最后的颜色用作过冲值的颜色。

import numpy as np; np.random.seed(1)
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.colors

lon,lat = np.meshgrid(np.arange(-180, 180, 10), np.arange(-85, 90, 10))
data = np.sort(np.random.rand(18, 36),axis=1)

# create 7 boundaries between 0 and 0.6, to have 6 intervals
boundaries = np.arange(0, .7, .1)
# create list of 7(!) colors from colormap
cmap_reds = plt.cm.get_cmap('Reds',len(boundaries))
colors = list(cmap_reds(np.arange(len(boundaries))))
#replace first color with white
colors[0] = "white"
cmap = matplotlib.colors.ListedColormap(colors[:-1], "")
# set over-color to last color of list 
cmap.set_over(colors[-1])

cm = plt.pcolormesh(lon,lat,data,
    cmap=cmap,
    norm = mpl.colors.BoundaryNorm(boundaries, ncolors=len(boundaries)-1, clip=False)
)
plt.colorbar(cm, extend="max")
plt.show()

enter image description here