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
for X,Y in data:
scatter(X, Y, c=numpy.random.rand(3,))
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.
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
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.
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))
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))