Was ist das triviale Beispiel dafür, wie zufällige Farben für die Übergabe an Plotfunktionen generiert werden?
Ich rufe Scatter innerhalb einer Schleife auf und möchte, dass jeder Plot eine andere Farbe hat.
for X,Y in data:
scatter(X, Y, c=??)
c: eine Farbe. c kann eine einzelne Farbformatzeichenfolge oder eine Folge von Farbspezifikationen der Länge N oder eine Folge von N Zahlen sein, die mithilfe der über kwargs angegebenen cmap und Norm auf Farben abgebildet werden sollen (siehe unten). Beachten Sie, dass c keine einzelne numerische RGB- oder RGBA-Sequenz sein sollte, da dies nicht von einem Array von Werten zu unterscheiden ist, die farblich zugeordnet werden sollen. c kann jedoch ein 2D-Array sein, in dem die Zeilen RGB oder RGBA sind.
python
matplotlib
John Mee
quelle
quelle
Antworten:
Basierend darauf und auf Ihrer Antwort: Es scheint mir, dass Sie tatsächlich
n
unterschiedliche Farben für Ihre Datensätze wünschen ; Sie möchten die Ganzzahlindizes0, 1, ..., n-1
unterschiedlichen RGB-Farben zuordnen. Etwas wie:Hier ist die Funktion, um es zu tun:
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)
Verwendung in Ihrem Pseudo- Code-Snippet in der Frage:
cmap = get_cmap(len(data)) for i, (X, Y) in enumerate(data): scatter(X, Y, c=cmap(i))
Ich habe die Zahl in meiner Antwort mit dem folgenden Code generiert:
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()
Getestet mit Python 2.7 und Matplotlib 1.5 sowie mit Python 3.5 und Matplotlib 2.0. Es funktioniert wie erwartet.
quelle
for X,Y in data: scatter(X, Y, c=numpy.random.rand(3,))
quelle
color=(random.uniform(0, 1), random.uniform(0, 1), random.uniform(0, 1))
scatter(X,Y, c=numpy.random.rand(len(X),3)
Ausarbeitung der Antwort von @ john-mee, wenn Sie beliebig lange Daten haben, aber keine streng eindeutigen Farben benötigen:
für Python 2:
from itertools import cycle cycol = cycle('bgrcmk') for X,Y in data: scatter(X, Y, c=cycol.next())
für Python 3:
from itertools import cycle cycol = cycle('bgrcmk') for X,Y in data: scatter(X, Y, c=next(cycol))
Dies hat den Vorteil, dass die Farben leicht zu kontrollieren sind und kurz sind.
quelle
Für einige Zeit war ich wirklich verärgert darüber, dass matplotlib keine Farbkarten mit zufälligen Farben generiert, da dies ein häufiger Bedarf für Segmentierungs- und Clustering-Aufgaben ist.
Indem wir nur zufällige Farben erzeugen, können wir mit einigen enden, die zu hell oder zu dunkel sind, was die Visualisierung schwierig macht. Außerdem muss die erste oder letzte Farbe normalerweise schwarz sein und den Hintergrund oder die Ausreißer darstellen. Also habe ich eine kleine Funktion für meine tägliche Arbeit geschrieben
Hier ist das Verhalten davon:
new_cmap = rand_cmap(100, type='bright', first_color_black=True, last_color_black=False, verbose=True)
Dann verwenden Sie einfach new_cmap als Farbkarte auf matplotlib:
ax.scatter(X,Y, c=label, cmap=new_cmap, vmin=0, vmax=num_labels)
Der Code ist hier:
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
Es ist auch auf Github: https://github.com/delestro/rand_cmap
quelle
Bei weniger als 9 Datensätzen:
colors = "bgrcmykw" color_index = 0 for X,Y in data: scatter(X,Y, c=colors[color_index]) color_index += 1
quelle
Da die Frage ist
How to generate random colors in matplotlib?
und ich nach einer Antwort bezüglich gesucht habepie plots
, denke ich, dass es sich lohnt, hier eine Antwort zu geben (fürpies
)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()
Ausgabe
quelle
Hier ist eine präzisere Version von Alis Antwort, die eine bestimmte Farbe pro Handlung angibt:
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))
quelle
Basierend auf Alis und Champitoads Antwort:
Wenn Sie verschiedene Paletten für dieselbe ausprobieren möchten, können Sie dies in wenigen Zeilen tun:
cmap=plt.cm.get_cmap(plt.cm.viridis,143)
^ 143 ist die Anzahl der Farben, die Sie abtasten
Ich habe 143 ausgewählt, weil hier die gesamte Farbpalette auf der Farbkarte ins Spiel kommt. Sie können bei jeder Iteration die n-te Farbe abtasten, um den Farbkarteneffekt zu erzielen.
n=20 for i,(x,y) in enumerate(points): plt.scatter(x,y,c=cmap(n*i))
quelle
Verbesserung der Antwort https://stackoverflow.com/a/14720445/6654512 für die Arbeit mit Python3. Dieser Code erzeugte manchmal Zahlen größer als 1 und matplotlib warf einen Fehler aus.
for X,Y in data: scatter(X, Y, c=numpy.random.random(3))
quelle
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])
quelle
Wenn Sie sicherstellen möchten, dass die Farben unterschiedlich sind, aber nicht wissen, wie viele Farben benötigt werden. Versuchen Sie so etwas. Es wählt Farben von gegenüberliegenden Seiten des Spektrums aus und erhöht systematisch die Granularität.
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()
Ausgabe
Vielen Dank an @Ali für die Bereitstellung der Basisimplementierung.
quelle