Matplotlib में यादृच्छिक रंग कैसे उत्पन्न करें?


87

प्लॉटिंग फ़ंक्शंस में पास होने के लिए यादृच्छिक रंगों को कैसे उत्पन्न किया जाए, इसका क्या तुच्छ उदाहरण है?

मैं एक लूप के अंदर बिखराव को बुला रहा हूं और प्रत्येक प्लॉट को एक अलग रंग चाहता हूं।

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

c: एक रंग। सी एक एकल रंग प्रारूप स्ट्रिंग, या लंबाई एन के रंग विनिर्देशों का एक अनुक्रम हो सकता है, या क्रैग्स के माध्यम से निर्दिष्ट सेमीपैक और मानक का उपयोग करके रंगों को मैप करने के लिए एन नंबर का एक अनुक्रम हो सकता है (नीचे देखें)। ध्यान दें कि ग एक एकल संख्यात्मक आरजीबी या RGBA अनुक्रम नहीं होना चाहिए, क्योंकि यह कॉल-अप करने के लिए मूल्यों की एक सरणी से अप्रभेद्य है। c, एक 2-D सरणी हो सकती है जिसमें पंक्तियाँ RGB या RGBA हैं, हालाँकि।


1
बेतरतीब ढंग से क्या से चुना? यदि आप सभी उपलब्ध रंगों में से यादृच्छिक रूप से चुनते हैं, तो आपको कुछ अलग-अलग रंगों का एक अजीब मिश्रण मिल सकता है और कुछ को समान रूप से भेद करना मुश्किल हो सकता है।
ब्रेनबार

जवाबों:


141

मैं एक लूप के अंदर बिखराव को बुला रहा हूं और प्रत्येक प्लॉट को एक अलग रंग में चाहता हूं।

उसके आधार पर, और आपके जवाब पर: यह मुझे लगता है कि आप वास्तव में अपने डेटासेट के लिए n अलग-अलग रंग चाहते हैं ; आप 0, 1, ..., n-1अलग-अलग RGB रंगों में पूर्णांक सूचकांकों को मैप करना चाहते हैं। कुछ इस तरह:

रंग करने के लिए मानचित्रण सूचकांक

यहाँ यह करने के लिए समारोह है:

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)

प्रश्न में आपके छद्म कोड स्निपेट का उपयोग :

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

मैंने निम्नलिखित कोड के साथ अपने उत्तर में आंकड़ा उत्पन्न किया:

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()

दोनों पायथन 2.7 और matplotlib 1.5 के साथ परीक्षण किया, और Python 3.5 और matplotlib 2.0 के साथ। यह उम्मीद के मुताबिक काम करता है।


1
@ user1941407 धन्यवाद! :) काश, मुझे पता होता कि किसी ने उत्तर को अस्वीकार क्यों कर दिया।
अली

7
शायद यह जटिल है
इंग्रिड

1
काम करने के लिए प्रतीत नहीं होता? अजगर सांत्वना में प्लग करने के लिए प्रतीत नहीं होता है।
mjwrazor

@mjwrazor क्षमा करें, मैं अनुसरण नहीं करता। क्या आप विस्तृत कर सकते हैं कि "क्या काम नहीं करता है"?
अली

मैंने पायथन कंसोल में विधि को रखने की कोशिश की, कंसोल इसे कभी नहीं पढ़ता है। इसके अलावा अपने तरीके के अंत में तर्क का कोई मतलब नहीं है। क्यों एक विधि है कि एक और विधि है कि एक निष्पादन विधि लौटा देता है। सिर्फ निष्पादित विधि वापस क्यों नहीं?
म्स्वजोर

76
for X,Y in data:
   scatter(X, Y, c=numpy.random.rand(3,))

1
क्या होगा अगर वहाँ तीन मूल्यों की साजिश है?
पांडा -34

1
क्या R, G और B घटकों के 3 मानों के लिए 3 खड़ा है?
क्षितिज बजराचार्य

सुन्न के बिना, आप का उपयोग कर सकते हैंcolor=(random.uniform(0, 1), random.uniform(0, 1), random.uniform(0, 1))
azzamsa

2
अधिक कुशल और कम टाइपिंग:scatter(X,Y, c=numpy.random.rand(len(X),3)
क्वालिया

31

यदि आप मनमाने ढंग से लंबे डेटा है, लेकिन @ john-mee के उत्तर को विस्तृत करते हैं, लेकिन इसके लिए आपको अद्वितीय रंगों की आवश्यकता नहीं है:

अजगर 2 के लिए:

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

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

अजगर 3 के लिए:

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

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

इसका यह फायदा है कि रंगों को नियंत्रित करना आसान है और यह छोटा है।


27

कुछ समय के लिए मैं वास्तव में इस तथ्य से नाराज था कि मैटप्लोटलिब यादृच्छिक रंगों के साथ कॉलर्मैप्स उत्पन्न नहीं करता है, क्योंकि यह विभाजन और क्लस्टरिंग कार्यों के लिए एक सामान्य आवश्यकता है।

बस यादृच्छिक रंग उत्पन्न करके हम कुछ के साथ समाप्त हो सकते हैं जो बहुत उज्ज्वल या बहुत अंधेरा हैं, जिससे दृश्य मुश्किल हो जाता है। इसके अलावा, आमतौर पर हमें पहले या आखिरी रंग की आवश्यकता होती है जो काला हो, पृष्ठभूमि या आउटलेर का प्रतिनिधित्व करता है। इसलिए मैंने अपने रोजमर्रा के काम के लिए एक छोटा सा कार्य लिखा है

यहाँ इसका व्यवहार है:

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

कोलोरैप उत्पन्न किया

बस आप matplotlib पर अपने colormap के रूप में new_cmap का उपयोग करें:

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


2
धन्यवाद। यह बहुत उपयोगी था।
राख

15

जब 9 से कम डेटासेट:

colors = "bgrcmykw"
color_index = 0

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

12

चूंकि प्रश्न है How to generate random colors in matplotlib?और जैसा कि मैं एक उत्तर के विषय में खोज रहा था pie plots, मुझे लगता है कि यह यहां (के लिए pies) उत्तर देने के लायक है

import numpy as np
from random import sample
import matplotlib.pyplot as plt
import matplotlib.colors as pltc
all_colors = [k for k,v in pltc.cnames.items()]

fracs = np.array([600, 179, 154, 139, 126, 1185])
labels = ["label1", "label2", "label3", "label4", "label5", "label6"]
explode = ((fracs == max(fracs)).astype(int) / 20).tolist()

for val in range(2):
    colors = sample(all_colors, len(fracs))
    plt.figure(figsize=(8,8))
    plt.pie(fracs, labels=labels, autopct='%1.1f%%', 
            shadow=True, explode=explode, colors=colors)
    plt.legend(labels, loc=(1.05, 0.7), shadow=True)
    plt.show()

उत्पादन

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें


1
अरे, यह वही है जो मैं देख रहा हूं। हालाँकि, आपकी दूसरी तस्वीर में (यह मेरे साथ भी होता है) आपको लगभग समान रंग (बेज / सफेद) मिलते हैं। क्या इस दृष्टिकोण का उपयोग करना संभव है लेकिन एक तरह से नमूना है जो अधिक विशिष्ट रंगों को चुनता है?
आर्मरा

9

यहाँ अली के उत्तर का एक और संक्षिप्त संस्करण दिया गया है, जो एक अलग रंग प्रति प्लॉट देता है:

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))

4

अली और चंपतोड के जवाब पर आधारित:

यदि आप उसी के लिए अलग-अलग पट्टियाँ आज़माना चाहते हैं, तो आप कुछ लाइनों में ऐसा कर सकते हैं:

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

^ 143 उन रंगों की संख्या है जिनका आप नमूना ले रहे हैं

मैंने १४३ को चुना क्योंकि कोलोरैप पर रंगों की पूरी रेंज यहाँ खेल में आती है। आप क्या कर सकते हैं colormap प्रभाव प्राप्त करने के लिए हर पुनरावृत्ति को nth रंग का नमूना दें।

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


2

पायथन 3 के साथ काम करने के लिए उत्तर https://stackoverflow.com/a/14720445/6654512 सुधारे। कोड का वह टुकड़ा कभी-कभी 1 से अधिक संख्या उत्पन्न करेगा और matplotlib एक त्रुटि फेंक देगा।

for X,Y in data:
   scatter(X, Y, c=numpy.random.random(3))

1
enter code here

import numpy as np

clrs = np.linspace( 0, 1, 18 )  # It will generate 
# color only for 18 for more change the number
np.random.shuffle(clrs)
colors = []
for i in range(0, 72, 4):
    idx = np.arange( 0, 18, 1 )
    np.random.shuffle(idx)
    r = clrs[idx[0]]
    g = clrs[idx[1]]
    b = clrs[idx[2]]
    a = clrs[idx[3]]
    colors.append([r, g, b, a])

ग्राफ को खींचते समय इस रंग सूची को रंग में निर्दिष्ट करें
संतोष मगदुम

1

यदि आप यह सुनिश्चित करना चाहते हैं कि रंग अलग-अलग हों - लेकिन यह नहीं जानते कि कितने रंगों की आवश्यकता है। कुछ इस तरह की कोशिश करो। यह स्पेक्ट्रम के विपरीत पक्षों से रंगों का चयन करता है और व्यवस्थित रूप से ग्रैन्युलैरिटी बढ़ाता है।

import math

def calc(val, max = 16):
    if val < 1:
        return 0
    if val == 1:
        return max

    l = math.floor(math.log2(val-1))    #level 
    d = max/2**(l+1)                    #devision
    n = val-2**l                        #node
    return d*(2*n-1)
import matplotlib.pyplot as plt

N = 16
cmap = cmap = plt.cm.get_cmap('gist_rainbow', N)

fig, axs = plt.subplots(2)
for ax in axs:
    ax.set_xlim([ 0, N])
    ax.set_ylim([-0.5, 0.5])
    ax.set_yticks([])

for i in range(0,N+1):
    v = int(calc(i, max = N))
    rect0 = plt.Rectangle((i, -0.5), 1, 1, facecolor=cmap(i))
    rect1 = plt.Rectangle((i, -0.5), 1, 1, facecolor=cmap(v))
    axs[0].add_artist(rect0)
    axs[1].add_artist(rect1)

plt.xticks(range(0, N), [int(calc(i, N)) for i in range(0, N)])
plt.show()

उत्पादन

आधार कार्यान्वयन प्रदान करने के लिए @Ali को धन्यवाद।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.