How to generate random colors in matplotlib?

前端 未结 11 2219
长情又很酷
长情又很酷 2020-12-12 16:13

What\'s the trivial example of how to generate random colors for passing to plotting functions?

I\'m calling scatter inside a loop and want each plot a different col

相关标签:
11条回答
  • 2020-12-12 16:18
    for X,Y in data:
       scatter(X, Y, c=numpy.random.rand(3,))
    
    0 讨论(0)
  • 2020-12-12 16:18

    elaborating @john-mee 's answer, if you have arbitrarily long data but don't need strictly unique colors:

    for python 2:

    from itertools import cycle
    cycol = cycle('bgrcmk')
    
    for X,Y in data:
        scatter(X, Y, c=cycol.next())
    

    for python 3:

    from itertools import cycle
    cycol = cycle('bgrcmk')
    
    for X,Y in data:
        scatter(X, Y, c=next(cycol))
    

    this has the advantage that the colors are easy to control and that it's short.

    0 讨论(0)
  • 2020-12-12 16:18

    Since the question is How to generate random colors in matplotlib? and as I was searching for an answer concerning pie plots, I think it is worth to put an answer here (for 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()
    

    Output

    0 讨论(0)
  • 2020-12-12 16:18

    If you want to ensure the colours are distinct - but don't know how many colours are needed. Try something like this. It selects colours from opposite sides of the spectrum and systematically increases granularity.

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

    output

    Thanks to @Ali for providing the base implementation.

    0 讨论(0)
  • 2020-12-12 16:24

    Based on Ali's and Champitoad's answer:

    If you want to try different palettes for the same, you can do this in a few lines:

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

    ^143 being the number of colours you're sampling

    I picked 143 because the entire range of colours on the colormap comes into play here. What you can do is sample the nth colour every iteration to get the colormap effect.

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

    0 讨论(0)
  • 2020-12-12 16:26

    Here is a more concise version of Ali's answer giving one distinct color per plot :

    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 讨论(0)
提交回复
热议问题