簡體   English   中英

Matplotlib 中非線性顏色條的統一刻度標簽

[英]Uniform tick labels for non-linear colorbar in Matplotlib

我正在尋找一種解決方案來創建具有統一刻度標簽(沿顏色條等間距)的顏色條,即使邊界是非線性的。 目前,由於刻度是根據邊界值按比例間隔的,所以顏色條的頂部被拉伸得很大,而底部被壓縮得如此之快,以至於無法看到哪個 colors 對應於哪個值。 我想保持相同的顏色/值組合,但帶有刻度 label 間距,使顏色條清晰易讀。

我使用當前代碼獲得的顏色條:
1

這是我使用的代碼:

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 之間。

對於BoundaryNormnp.interp計算所有中間值以獲得 256 個不同的級別,而不是原來的 13 個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM