[英]Uniform tick labels for non-linear colorbar in Matplotlib
我正在尋找一種解決方案來創建具有統一刻度標簽(沿顏色條等間距)的顏色條,即使邊界是非線性的。 目前,由於刻度是根據邊界值按比例間隔的,所以顏色條的頂部被拉伸得很大,而底部被壓縮得如此之快,以至於無法看到哪個 colors 對應於哪個值。 我想保持相同的顏色/值組合,但帶有刻度 label 間距,使顏色條清晰易讀。
我使用當前代碼獲得的顏色條:
這是我使用的代碼:
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')
A BoundaryNorm
似乎是您正在尋找的:
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 個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.