为了账号安全,请及时绑定邮箱和手机立即绑定

Matplotlib 中非线性颜色条的统一刻度标签

Matplotlib 中非线性颜色条的统一刻度标签

繁花如伊 2023-03-30 09:49:44
我正在寻找一种解决方案来创建具有统一刻度标签的颜色条(沿颜色条等距),即使边界是非线性的。目前,由于刻度线是根据边界值按比例分布的,因此颜色条的顶部被拉伸得相当厉害,而底部被压缩得很厉害,以至于无法看到哪些颜色对应于哪个值。我想保持相同的颜色/值组合,但带有使颜色栏清晰可见的刻度标签间距。我使用当前代码获得的颜色条:这是我使用的代码:import matplotlib as mplfrom matplotlib.backends.backend_agg import FigureCanvasAggfrom matplotlib.colors import LinearSegmentedColormapfrom matplotlib.figure import Figure# databounds = [0.1, 0.25, 0.5, 1, 2.5, 5, 7.5, 10, 15, 20, 25, 50, 100]style_color = [[0, 0, 127],               [0, 0, 197],               [0, 21, 254],               [0, 126, 254],               [0, 231, 254],               [68, 253, 186],               [153, 254, 101],               [238, 254, 16],               [254, 187, 0],               [254, 101, 0],               [254, 16, 0],               [197, 0, 0],               [127, 0, 0],               [127, 0, 0]]# transform color rgb value to 0-1 rangecolor_arr = []for color in style_color:    rgb = [float(value)/255 for value in color]    color_arr.append(rgb)# normalize bound valuesnorm = mpl.colors.Normalize(vmin=min(bounds), vmax=max(bounds))normed_vals = norm(bounds)# create a colormapcmap = LinearSegmentedColormap.from_list(    'my_palette',    list(zip(normed_vals, color_arr[:-1])),    N=256    )cmap.set_over([color for color in color_arr[-1]])cmap.set_under([color for color in color_arr[0]])# create a figurefig = Figure(figsize=(2, 5))canvas = FigureCanvasAgg(fig)ax = fig.add_subplot(121)# create the colorbarcb = mpl.colorbar.ColorbarBase(ax,                               cmap=cmap,                               norm=norm,                               extend='max',                               ticks=bounds)fig.savefig('non-linear_colorbar')
查看完整描述

1 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

ABoundaryNorm似乎是你要找的东西:


import matplotlib as mpl

from matplotlib.colors import LinearSegmentedColormap, BoundaryNorm

from matplotlib import pyplot as plt


# data

bounds = [0.1, 0.25, 0.5, 1, 2.5, 5, 7.5, 10, 15, 20, 25, 50, 100]

style_color = [[0, 0, 127],

               [0, 0, 197],

               [0, 21, 254],

               [0, 126, 254],

               [0, 231, 254],

               [68, 253, 186],

               [153, 254, 101],

               [238, 254, 16],

               [254, 187, 0],

               [254, 101, 0],

               [254, 16, 0],

               [197, 0, 0],

               [127, 0, 0],

               [127, 0, 0]]


# transform color rgb value to 0-1 range

color_arr = []

for color in style_color:

    rgb = [float(value) / 255 for value in color]

    color_arr.append(rgb)


# normalize bound values

norm = mpl.colors.BoundaryNorm(bounds, ncolors=256)


# create a colormap

cmap = LinearSegmentedColormap.from_list('my_palette', color_arr, N=256)


# create a figure

fig, ax = plt.subplots(figsize=(2, 5), gridspec_kw={'left': 0.4, 'right': 0.5})


# create the colorbar

cb = mpl.colorbar.ColorbarBase(ax, cmap=cmap, norm=norm, extend='max', ticks=bounds)

plt.show()

//img1.sycdn.imooc.com//6424eb080001ca6006520222.jpg

PS:如果你需要一个平滑的颜色条,你可以拉伸边界:


import numpy as np


bounds = [0.1, 0.25, 0.5, 1, 2.5, 5, 7.5, 10, 15, 20, 25, 50, 100]

stretched_bounds = np.interp(np.linspace(0, 1, 257), np.linspace(0, 1, len(bounds)), bounds)


# normalize stretched bound values

norm = mpl.colors.BoundaryNorm(stretched_bounds, ncolors=256)


# ....

cb = mpl.colorbar.ColorbarBase(ax, cmap=cmap, norm=norm, extend='max', ticks=bounds)

//img1.sycdn.imooc.com//6424eb170001d11c06540256.jpg

PS:new_y = np.interp(new_x, old_x, old_y)通过首先在旧 x 的数组中查找 x 并找到对应的旧 y 来为 y 插入新值。当新 x 位于两个旧 x 之间时,新 y 将按比例位于旧 y 之间。

对于BoundaryNormnp.interp计算所有中间值以获得 256 个不同的级别,而不是原来的 13 个。


查看完整回答
反对 回复 2023-03-30
  • 1 回答
  • 0 关注
  • 103 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信