簡體   English   中英

旋轉 matplotlib 顏色圖

[英]Rotate matplotlib colourmap

ProPlot Python package 為 Matplotlib 庫添加了其他功能,包括顏色圖操作。 對我特別有吸引力的一個功能是旋轉/移動顏色圖的能力。 給你舉個例子:

import proplot as pplot
import matplotlib.pyplot as plt
import numpy as np

state = np.random.RandomState(51423)
data = state.rand(30, 30).cumsum(axis=1)

fig, axes = plt.subplots(ncols=3, figsize=(9, 4))
fig.patch.set_facecolor("white")

axes[0].pcolormesh(data, cmap="Blues")
axes[0].set_title("Blues")
axes[1].pcolormesh(data, cmap="Blues_r")
axes[1].set_title("Reversed Blues")
axes[2].pcolormesh(data, cmap="Blues_s")
axes[2].set_title("Rotated Blues")

plt.tight_layout()
plt.show()

在此處輸入圖像描述

在第三列中,您會看到 180° 旋轉的Blues版本。 目前 ProPlot 存在一個錯誤,該錯誤不允許用戶將繪圖樣式恢復為 Matplotlib 的默認樣式,所以我想知道是否有一種簡單的方法可以在 Matplotlib 中旋轉顏色圖而不使用 ProPlot。 我總是發現 Matplotlib 中的 cmap 操作有點神秘,因此非常感謝任何幫助。

如果您想要做的是改變顏色圖,這可以(相對)容易地完成:

def shift_cmap(cmap, frac):
    """Shifts a colormap by a certain fraction.

    Keyword arguments:
    cmap -- the colormap to be shifted. Can be a colormap name or a Colormap object
    frac -- the fraction of the colorbar by which to shift (must be between 0 and 1)
    """
    N=256
    if isinstance(cmap, str):
        cmap = plt.get_cmap(cmap)
    n = cmap.name
    x = np.linspace(0,1,N)
    out = np.roll(x, int(N*frac))
    new_cmap = matplotlib.colors.LinearSegmentedColormap.from_list(f'{n}_s', cmap(out))
    return new_cmap

示范:

x = np.linspace(0,1,100)
x = np.vstack([x,x])

cmap1 = plt.get_cmap('Blues')
cmap2 = shift_cmap(cmap1, 0.25)

fig, (ax1, ax2) = plt.subplots(2,1)
ax1.imshow(x, aspect='auto', cmap=cmap1)
ax2.imshow(x, aspect='auto', cmap=cmap2)

在此處輸入圖像描述

要反轉ListedColormap ,有一個內置的reversed()但對於預期的旋轉,我們必須創建自己的 function。

#fake data generation 
import numpy as np
np.random.seed(123)
#numpy array containing x, y, and color
arr = np.random.random(30).reshape(3, 10)


from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap

def rotate_cm(co_map, deg=180): 
    #define a function where the colormap is rotated by a certain degree 
    #180° shifts by 50%, 360° no change
    n = co_map.N
    #if rotating in the opposite direction feels more intuitive, reverse the sign here
    deg = -deg%360
    if deg < 0:
        deg += 360
    cutpoint = n * deg // 360
    new_col_arr = [co_map(i) for i in range(cutpoint, n)] + [co_map(i) for i in range(cutpoint)]
    return ListedColormap(new_col_arr)
     

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(21,7))
#any listed colormap
my_cm = plt.cm.get_cmap("inferno")

#normal color map
cb1 = ax1.scatter(*arr[:2,:], c=arr[2,:], cmap=my_cm, marker="o")
plt.colorbar(cb1, ax=ax1)
ax1.set_title("regular colormap")

#reversed colormap
cb2 = ax2.scatter(*arr[:2,:], c=arr[2,:], cmap=my_cm.reversed(), marker="o")
plt.colorbar(cb2, ax=ax2)
ax2.set_title("reversed colormap")

#rotated colormap
cb3 = ax3.scatter(*arr[:2,:], c=arr[2,:], cmap=rotate_cm(my_cm, 90), marker="o")
#you can also combine the rotation with reversed()
#cb3 = ax3.scatter(*arr[:2,:], c=arr[2,:], cmap=rotate_cm(my_cm, 90).reversed(), marker="o")
plt.colorbar(cb3, ax=ax3)
ax3.set_title("colormap rotated by 90°")


plt.show()

樣品 output: ![在此處輸入圖像描述

暫無
暫無

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

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