2013-02-06 261 views
35

什麼是如何生成隨機顏色傳遞到繪圖功能的簡單例子?如何在matplotlib中生成隨機顏色?

我打電話散佈在一個循環內,並希望每個陰謀不同的顏色。

for X,Y in data: 
    scatter(X, Y, c=??) 

C: 的顏色。 c可以是單色格式字符串,也可以是長度爲N的顏色規格序列,也可以是使用通過kwargs指定的cmap和範數(參見下文)映射到顏色的N個數字序列。請注意,c不應該是單個數字RGB或RGBA序列,因爲它與要進行彩色映射的值數組難以區分。然而,c可以是其中行是RGB或RGBA的二維陣列。

+0

隨機選擇什麼?如果您從所有可用的顏色中隨機選擇,您可能會得到一些不同顏色的奇怪組合,有些非常相似,難以區分。 – BrenBarn

回答

36
for X,Y in data: 
    scatter(X, Y, c=numpy.random.rand(3,1)) 
+7

我不得不使用'c = numpy.random.rand(3,)',否則我得到一個錯誤... – heltonbiker

+1

如果有三個值要繪製? –

9

當小於9個集:

colors = "bgrcmykw" 
color_index = 0 

for X,Y in data: 
    scatter(X,Y, c=colors[color_index]) 
    color_index += 1 
75

我打電話循環內部散射,並希望以不同的顏色各小區。

此基礎上,並在您的回答:在我看來,你真的想n不同顏色供您的數據集; 您想要將整數索引0, 1, ..., n-1映射到不同的RGB顏色。喜歡的東西:

mapping index to color

下面是做到這一點的功能:

cmap = get_cmap(len(data)) 
for i, (X, Y) in enumerate(data): 
    scatter(X, Y, c=cmap(i)) 

:在您的問題僞 -code片段

import matplotlib.pyplot as plt 

def get_cmap(n, name='hsv'): 
    '''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct 
    RGB color; the keyword argument name must be a standard mpl colormap name.''' 
    return plt.cm.get_cmap(name, n) 

用法

我生成了th在我的答案E圖用下面的代碼:

import matplotlib.pyplot as plt 

def get_cmap(n, name='hsv'): 
    '''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct 
    RGB color; the keyword argument name must be a standard mpl colormap name.''' 
    return plt.cm.get_cmap(name, n) 

def main(): 
    N = 30 
    fig=plt.figure() 
    ax=fig.add_subplot(111) 
    plt.axis('scaled') 
    ax.set_xlim([ 0, N]) 
    ax.set_ylim([-0.5, 0.5]) 
    cmap = get_cmap(N) 
    for i in range(N): 
     rect = plt.Rectangle((i, -0.5), 1, 1, facecolor=cmap(i)) 
     ax.add_artist(rect) 
    ax.set_yticks([]) 
    plt.show() 

if __name__=='__main__': 
    main() 

測試兩者的Python 2.7 & matplotlib 1.5,並與Python 3.5 & matplotlib 2.0。它按預期工作。

+0

答案有什麼問題?爲什麼downvote? – Ali

+1

@ user1941407謝謝! :)我希望我知道爲什麼有人匿名低估了答案。 – Ali

+3

也許它很複雜 – ingrid

16

闡述@約翰 - 眉的回答,如果你有任意長的數據,但並不需要嚴格獨特的顏色:

爲蟒2:

from itertools import cycle 
cycol = cycle('bgrcmk') 

for X,Y in data: 
    scatter(X, Y, c=cycol.next()) 

爲Python 3:

from itertools import cycle 
cycol = cycle('bgrcmk') 

for X,Y in data: 
    scatter(X, Y, c=next(cycol)) 

這樣做的好處是色彩易於控制,而且很短。

10

一段時間以來,我對matplotlib不會生成隨機顏色的colormap的事實感到非常惱火,因爲這是分割和聚類任務的常見需求。

通過只產生隨機顏色,我們可能會結束一些太亮或太暗,使可視化變得困難。此外,通常我們需要第一個或最後一個顏色爲黑色,代表背景或異常值。所以我寫了一個小功能對我的日常工作

下面是它的行爲:

new_cmap = rand_cmap(100, type='bright', first_color_black=True, last_color_black=False, verbose=True) Generated colormap

比你只需要使用new_cmap爲您的色彩表上matplotlib:

ax.scatter(X,Y, c=label, cmap=new_cmap, vmin=0, vmax=num_labels)

代碼在這裏:


def rand_cmap(nlabels, type='bright', first_color_black=True, last_color_black=False, verbose=True): 
    """ 
    Creates a random colormap to be used together with matplotlib. Useful for segmentation tasks 
    :param nlabels: Number of labels (size of colormap) 
    :param type: 'bright' for strong colors, 'soft' for pastel colors 
    :param first_color_black: Option to use first color as black, True or False 
    :param last_color_black: Option to use last color as black, True or False 
    :param verbose: Prints the number of labels and shows the colormap. True or False 
    :return: colormap for matplotlib 
    """ 
    from matplotlib.colors import LinearSegmentedColormap 
    import colorsys 
    import numpy as np

if type not in ('bright', 'soft'): print ('Please choose "bright" or "soft" for type') return if verbose: print('Number of labels: ' + str(nlabels)) # Generate color map for bright colors, based on hsv if type == 'bright': randHSVcolors = [(np.random.uniform(low=0.0, high=1), np.random.uniform(low=0.2, high=1), np.random.uniform(low=0.9, high=1)) for i in xrange(nlabels)] # Convert HSV list to RGB randRGBcolors = [] for HSVcolor in randHSVcolors: randRGBcolors.append(colorsys.hsv_to_rgb(HSVcolor[0], HSVcolor[1], HSVcolor[2])) if first_color_black: randRGBcolors[0] = [0, 0, 0] if last_color_black: randRGBcolors[-1] = [0, 0, 0] random_colormap = LinearSegmentedColormap.from_list('new_map', randRGBcolors, N=nlabels) # Generate soft pastel colors, by limiting the RGB spectrum if type == 'soft': low = 0.6 high = 0.95 randRGBcolors = [(np.random.uniform(low=low, high=high), np.random.uniform(low=low, high=high), np.random.uniform(low=low, high=high)) for i in xrange(nlabels)] if first_color_black: randRGBcolors[0] = [0, 0, 0] if last_color_black: randRGBcolors[-1] = [0, 0, 0] random_colormap = LinearSegmentedColormap.from_list('new_map', randRGBcolors, N=nlabels) # Display colorbar if verbose: from matplotlib import colors, colorbar from matplotlib import pyplot as plt fig, ax = plt.subplots(1, 1, figsize=(15, 0.5)) bounds = np.linspace(0, nlabels, nlabels + 1) norm = colors.BoundaryNorm(bounds, nlabels) cb = colorbar.ColorbarBase(ax, cmap=random_colormap, norm=norm, spacing='proportional', ticks=None, boundaries=bounds, format='%1i', orientation=u'horizontal') return random_colormap

這也是在GitHub上: https://github.com/delestro/rand_cmap

+0

謝謝。這非常有用。 – Ash

+0

你如何將它添加到anaconda? – mjwrazor

4

這是阿里的回答每小區給一個不同顏色的更簡潔的版本:

import matplotlib.pyplot as plt 

N = len(data) 
cmap = plt.cm.get_cmap("hsv", N+1) 
for i in range(N): 
    X,Y = data[i] 
    plt.scatter(X, Y, c=cmap(i)) 
0

基於阿里和Champitoad的回答是:

如果你想嘗試不同的調色板一樣,你可以在幾行做到這一點:

cmap=plt.cm.get_cmap(plt.cm.viridis,143)

^143福祉你正在採樣的顏色的數量

我選擇了143,因爲色彩地圖上的所有顏色範圍都在這裏發揮作用。你可以做的是每次迭代採樣第n個顏色來獲得色彩映射效果。

n=20 for i,(x,y) in enumerate(points): plt.scatter(x,y,c=cmap(n*i))