python - Matplotlib 中非线性颜色条的统一刻度标签
问题描述
我正在寻找一种解决方案来创建具有统一刻度标签(沿颜色条等间距)的颜色条,即使边界是非线性的。目前,由于刻度是根据边界值按比例间隔开的,所以颜色条的顶部被拉伸得很厉害,而底部被压缩得如此之快,以至于无法看到哪些颜色对应于哪个值。我想保持相同的颜色/值组合,但带有使颜色条清晰易读的刻度标签间距。
我使用当前代码获得的颜色条:
这是我使用的代码:
import matplotlib as mpl
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.figure import Figure
# 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.Normalize(vmin=min(bounds), vmax=max(bounds))
normed_vals = norm(bounds)
# create a colormap
cmap = 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 figure
fig = Figure(figsize=(2, 5))
canvas = FigureCanvasAgg(fig)
ax = fig.add_subplot(121)
# create the colorbar
cb = mpl.colorbar.ColorbarBase(ax,
cmap=cmap,
norm=norm,
extend='max',
ticks=bounds)
fig.savefig('non-linear_colorbar')
解决方案
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()
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)
PS:new_y = np.interp(new_x, old_x, old_y)
通过首先在旧 x 的数组中查找 x,并找到对应的旧 y,为 y 插入新值。当新 x 位于两个旧 x 之间时,新 y 将按比例位于旧 y 之间。
对于BoundaryNorm
,np.interp
计算所有中间值以获得 256 个不同的级别,而不是原来的 13 个。
推荐阅读
- php - 在验证之前编辑请求数据
- azure - 拉取后 ACI 缓存 docker 图像
- r - 具有数字模式的字符串中的字符数(在 R 中)?
- c# - PDFsharp (1.50.5147) 设置 OwnerPassword 混淆了文档颜色
- python-sphinx - 构建文档时如何告诉 sphinx 忽略“包含”指令?
- python - 如何自定义 Django 的默认邮件模板?(smtpd)
- c - 如果条件为真,如何返回结构,如果条件为假,如何返回 int
- php - (Wordpress) 我将 WooCommerce 产品的模板更改为类别图像,但图像仍未显示
- hadoop - Hive Joins 可以在 Apache Nifi 中实现吗?
- laravel - 用关系复制一些数据