簡體   English   中英

使用 matplotlib 創建自己的顏色圖並繪制色標

[英]Create own colormap using matplotlib and plot color scale

我有以下問題,我想創建自己的顏色圖(紅混合紫混合藍),映射到 -2 和 +2 之間的值,並想用它來為我的繪圖中的點着色。 然后該圖應該具有右側的色階。

到目前為止,這就是我創建地圖的方式。 但我不確定它是否混合了顏色。

cmap = matplotlib.colors.ListedColormap(["red","violet","blue"], name='from_list', N=None)
m = cm.ScalarMappable(norm=norm, cmap=cmap)


這樣我將顏色映射到值。

colors = itertools.cycle([m.to_rgba(1.22), ..])


然后我繪制它:

for i in range(0, len(array_dg)):
  plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next())


我的問題是:
1.我無法繪制色標。
2. 我不完全確定我的比例是否創建了連續(平滑)的色階。

這里有一個關於 如何創建自定義顏色圖的說明性示例。 文檔字符串對於理解cdict的含義cdict 一旦你明白了,你可能會使用這樣的cdict

cdict = {'red':   ((0.0, 1.0, 1.0), 
                   (0.1, 1.0, 1.0),  # red 
                   (0.4, 1.0, 1.0),  # violet
                   (1.0, 0.0, 0.0)), # blue

         'green': ((0.0, 0.0, 0.0),
                   (1.0, 0.0, 0.0)),

         'blue':  ((0.0, 0.0, 0.0),
                   (0.1, 0.0, 0.0),  # red
                   (0.4, 1.0, 1.0),  # violet
                   (1.0, 1.0, 0.0))  # blue
          }

盡管cdict格式為您提供了很大的靈活性,但我發現對於簡單的漸變,其格式相當不直觀。 這是一個幫助生成簡單 LinearSegmentedColormaps 的實用函數:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors


def make_colormap(seq):
    """Return a LinearSegmentedColormap
    seq: a sequence of floats and RGB-tuples. The floats should be increasing
    and in the interval (0,1).
    """
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
    cdict = {'red': [], 'green': [], 'blue': []}
    for i, item in enumerate(seq):
        if isinstance(item, float):
            r1, g1, b1 = seq[i - 1]
            r2, g2, b2 = seq[i + 1]
            cdict['red'].append([item, r1, r2])
            cdict['green'].append([item, g1, g2])
            cdict['blue'].append([item, b1, b2])
    return mcolors.LinearSegmentedColormap('CustomMap', cdict)


c = mcolors.ColorConverter().to_rgb
rvb = make_colormap(
    [c('red'), c('violet'), 0.33, c('violet'), c('blue'), 0.66, c('blue')])
N = 1000
array_dg = np.random.uniform(0, 10, size=(N, 2))
colors = np.random.uniform(-2, 2, size=(N,))
plt.scatter(array_dg[:, 0], array_dg[:, 1], c=colors, cmap=rvb)
plt.colorbar()
plt.show()

在此處輸入圖片說明


順便說一下, for-loop

for i in range(0, len(array_dg)):
  plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next())

每次調用plt.plot繪制一個點。 這將適用於少量點,但對於許多點會變得非常慢。 plt.plot只能繪制一種顏色,但plt.scatter可以為每個點指定不同的顏色。 因此, plt.scatter是要走的路。

由於其他答案中使用的方法對於如此簡單的任務來說似乎相當復雜,因此這里有一個新答案:

代替的ListedColormap ,其產生的離散顏色表,你可以使用一個LinearSegmentedColormap 這可以使用from_list方法從列表輕松創建。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors

x,y,c = zip(*np.random.rand(30,3)*4-2)

norm=plt.Normalize(-2,2)
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["red","violet","blue"])

plt.scatter(x,y,c=c, cmap=cmap, norm=norm)
plt.colorbar()
plt.show()

在此處輸入圖片說明


更一般地說,如果您有一個值列表(例如[-2., -1, 2] )和相應的顏色(例如["red","violet","blue"] ),則第n個值應該對應於第n顏色,您可以標准化這些值並將它們作為元組提供給from_list方法。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors

x,y,c = zip(*np.random.rand(30,3)*4-2)

cvals  = [-2., -1, 2]
colors = ["red","violet","blue"]

norm=plt.Normalize(min(cvals),max(cvals))
tuples = list(zip(map(norm,cvals), colors))
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", tuples)

plt.scatter(x,y,c=c, cmap=cmap, norm=norm)
plt.colorbar()
plt.show()

在此處輸入圖片說明

如果你想自動創建一個通常用於表面圖的自定義發散顏色,這個模塊結合@unutbu 方法對我來說效果很好。

def diverge_map(high=(0.565, 0.392, 0.173), low=(0.094, 0.310, 0.635)):
    '''
    low and high are colors that will be used for the two
    ends of the spectrum. they can be either color strings
    or rgb color tuples
    '''
    c = mcolors.ColorConverter().to_rgb
    if isinstance(low, basestring): low = c(low)
    if isinstance(high, basestring): high = c(high)
    return make_colormap([low, c('white'), 0.5, c('white'), high])

高值和低值可以是字符串顏色名稱或 rgb 元組。 這是使用表面圖演示的結果:在此處輸入圖片說明

這似乎對我有用。

def make_Ramp( ramp_colors ): 
    from colour import Color
    from matplotlib.colors import LinearSegmentedColormap

    color_ramp = LinearSegmentedColormap.from_list( 'my_list', [ Color( c1 ).rgb for c1 in ramp_colors ] )
    plt.figure( figsize = (15,3))
    plt.imshow( [list(np.arange(0, len( ramp_colors ) , 0.1)) ] , interpolation='nearest', origin='lower', cmap= color_ramp )
    plt.xticks([])
    plt.yticks([])
    return color_ramp

custom_ramp = make_Ramp( ['#754a28','#893584','#68ad45','#0080a5' ] ) 

自定義色帶

暫無
暫無

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

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