web-dev-qa-db-de.com

Festlegen einer anderen Farbe für jede Serie im Streudiagramm auf Matplotlib

Angenommen, ich habe drei Datensätze:

X = [1,2,3,4]
Y1 = [4,8,12,16]
Y2 = [1,4,9,16]

Ich kann dieses Diagramm streuen:

from matplotlib import pyplot as plt
plt.scatter(X,Y1,color='red')
plt.scatter(X,Y2,color='blue')
plt.show()

Wie kann ich das mit 10 Sets machen?

Ich habe danach gesucht und konnte einen Hinweis darauf finden, was ich frage.

Edit: (hoffentlich) meine Frage klären

Wenn ich Scatter mehrmals aufrufe, kann ich nur bei jedem Scatter die gleiche Farbe einstellen. Ich weiß auch, dass ich ein Farbarray manuell einstellen kann, aber ich bin mir sicher, dass es eine bessere Möglichkeit gibt, dies zu tun. Meine Frage lautet dann: "Wie kann ich automatisch mehrere Datensätze mit unterschiedlichen Farben streuen?.

Wenn das hilft, kann ich jedem Datensatz leicht eine eindeutige Nummer zuweisen.

142
Yotam

Ich weiß nicht, was Sie mit "manuell" meinen. Sie können eine Farbkarte auswählen und ganz einfach ein Farbarray erstellen:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]

colors = cm.Rainbow(np.linspace(0, 1, len(ys)))
for y, c in Zip(ys, colors):
    plt.scatter(x, y, color=c)

Matplotlib graph with different colors

Oder Sie können mit itertools.cycle Ihren eigenen Farbwechsler erstellen und die Farben angeben, über die Sie eine Schleife erstellen möchten. Verwenden Sie next, um die gewünschte Farbe zu erhalten. Zum Beispiel mit 3 Farben:

import itertools

colors = itertools.cycle(["r", "b", "g"])
for y in ys:
    plt.scatter(x, y, color=next(colors))

Matplotlib graph with only 3 colors

Denken Sie mal darüber nach, vielleicht ist es sauberer, Zip auch beim ersten zu verwenden:

colors = iter(cm.Rainbow(np.linspace(0, 1, len(ys))))
for y in ys:
    plt.scatter(x, y, color=next(colors))
227
DSM

Die normale Methode zum Plotten von Plots mit Punkten in verschiedenen Farben in matplotlib besteht darin, eine Liste von Farben als Parameter zu übergeben.

Z.B.:

import matplotlib.pyplot
matplotlib.pyplot.scatter([1,2,3],[4,5,6],color=['red','green','blue'])

3 colors

Wenn Sie eine Liste mit Listen haben und diese pro Liste einfärben möchten. Ich denke, die eleganteste Methode ist die, die von @DSM vorgeschlagen wird. Machen Sie einfach eine Schleife und rufen Sie mehrfach auf, um zu streuen.

Aber wenn Sie es aus irgendeinem Grund mit nur einem Aufruf tun möchten, können Sie eine große Liste von Farben mit einem Listenverständnis und einer gewissen Unterteilung des Fußbodens erstellen:

import matplotlib
import numpy as np

X = [1,2,3,4]
Ys = np.array([[4,8,12,16],
      [1,4,9,16],
      [17, 10, 13, 18],
      [9, 10, 18, 11],
      [4, 15, 17, 6],
      [7, 10, 8, 7],
      [9, 0, 10, 11],
      [14, 1, 15, 5],
      [8, 15, 9, 14],
       [20, 7, 1, 5]])
nCols = len(X)  
nRows = Ys.shape[0]

colors = matplotlib.cm.Rainbow(np.linspace(0, 1, len(Ys)))

cs = [colors[i//len(X)] for i in range(len(Ys)*len(X))] #could be done with numpy's repmat
Xs=X*nRows #use list multiplication for repetition
matplotlib.pyplot.scatter(Xs,Ys.flatten(),color=cs)

All plotted

cs = [array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 ...
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00])]
42
Lyndon White

Eine einfache Lösung

Wenn Sie nur eine Art von Sammlungen haben (z. B. Streuung ohne Fehlerbalken), können Sie die Farben auch ändern, nachdem Sie sie geplottet haben. Dies ist manchmal einfacher.

import matplotlib.pyplot as plt
from random import randint
import numpy as np

#Let's generate some random X, Y data X = [ [frst group],[second group] ...]
X = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
Y = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
labels = range(1,len(X)+1)

fig = plt.figure()
ax = fig.add_subplot(111)
for x,y,lab in Zip(X,Y,labels):
        ax.scatter(x,y,label=lab)

Der einzige Code, den Sie benötigen:

#Now this is actually the code that you need, an easy fix your colors just cut and paste not you need ax.
colormap = plt.cm.Gist_ncar #nipy_spectral, Set1,Paired  
colorst = [colormap(i) for i in np.linspace(0, 0.9,len(ax.collections))]       
for t,j1 in enumerate(ax.collections):
    j1.set_color(colorst[t])


ax.legend(fontsize='small')

Die Ausgabe gibt Ihnen verschiedene Farben, selbst wenn Sie viele verschiedene Streudiagramme in demselben Unterdiagramm haben.

enter image description here

18
G M

Sie können die plot() -Funktion immer folgendermaßen verwenden:

import matplotlib.pyplot as plt

import numpy as np

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]
plt.figure()
for y in ys:
    plt.plot(x, y, 'o')
plt.show()

plot as scatter but changes colors

7
Ophir Carmi

Diese Frage ist vor Januar 2013 und Matplotlib 1.3.1 (August 2013), der ältesten stabilen Version, die Sie auf der Matpplotlib-Website finden, etwas knifflig. Aber danach ist es ziemlich trivial.

Da die aktuelle Version von matplotlib.pylab.scatter Die Zuweisung von: Array der Farbnamenzeichenfolge, Array der Gleitkommazahl mit Farbzuordnung, Array von RGB oder RGBA unterstützt.

diese Antwort widmet sich der unendlichen Leidenschaft von @ Oxinabox, die Version 2013 von mir im Jahr 2015 zu korrigieren.


sie haben zwei Möglichkeiten, den Befehl "Scatter" mit mehreren Farben in einem einzigen Aufruf zu verwenden.

  1. verwenden Sie als pylab.scatter - Befehlsunterstützung das RGBA-Array, um jede gewünschte Farbe zu erzeugen.

  2. anfang 2013 war dies noch nicht möglich, da der Befehl nur einzelne Farben für die gesamte Streupunktsammlung unterstützt. Als ich mein 10000-Linien-Projekt machte, fand ich eine allgemeine Lösung, um es zu umgehen. es ist also sehr klebrig, aber ich kann es in jeder Form, Farbe, Größe und Transparenz tun. Dieser Trick kann auch zum Zeichnen von Pfaden und Linien angewendet werden.

der Code ist auch vom Quellcode von pyplot.scatter inspiriert. Ich habe nur dupliziert, was Scatter macht, ohne es zum Zeichnen auszulösen.

der Befehl pyplot.scatter gibt ein PatchCollection Objekt zurück, in der Datei "matplotlib/collections.py" eine private Variable _facecolors in der Collection Klasse und eine Methode set_facecolors.

wenn Sie also Streupunkte zum Zeichnen haben, können Sie dies tun:

# rgbaArr is a N*4 array of float numbers you know what I mean
# X is a N*2 array of coordinates
# axx is the axes object that current draw, you get it from
# axx = fig.gca()

# also import these, to recreate the within env of scatter command 
import matplotlib.markers as mmarkers
import matplotlib.transforms as mtransforms
from matplotlib.collections import PatchCollection
import matplotlib.markers as mmarkers
import matplotlib.patches as mpatches


# define this function
# m is a string of scatter marker, it could be 'o', 's' etc..
# s is the size of the point, use 1.0
# dpi, get it from axx.figure.dpi
def addPatch_point(m, s, dpi):
    marker_obj = mmarkers.MarkerStyle(m)
    path = marker_obj.get_path()
    trans = mtransforms.Affine2D().scale(np.sqrt(s*5)*dpi/72.0)
    ptch = mpatches.PathPatch(path, fill = True, transform = trans)
    return ptch

patches = []
# markerArr is an array of maker string, ['o', 's'. 'o'...]
# sizeArr is an array of size float, [1.0, 1.0. 0.5...]

for m, s in Zip(markerArr, sizeArr):
    patches.append(addPatch_point(m, s, axx.figure.dpi))

pclt = PatchCollection(
                patches,
                offsets = Zip(X[:,0], X[:,1]),
                transOffset = axx.transData)

pclt.set_transform(mtransforms.IdentityTransform())
pclt.set_edgecolors('none') # it's up to you
pclt._facecolors = rgbaArr

# in the end, when you decide to draw
axx.add_collection(pclt)
# and call axx's parent to draw_idle()
6
Hualin

Das funktioniert bei mir:

verwenden Sie für jede Serie einen Zufallsgenerator für RGB-Farben

c = color[np.random.random_sample(), np.random.random_sample(), np.random.random_sample()]
1
bracoo