Ich versuche, einen diskreten Farbbalken für ein Streudiagramm in matplotlib zu erstellen
Ich habe meine x-, y-Daten und für jeden Punkt einen ganzzahligen Tag-Wert, den ich mit einer eindeutigen Farbe darstellen möchte, z
plt.scatter(x, y, c=tag)
Normalerweise ist das Tag eine Ganzzahl im Bereich von 0 bis 20, aber der genaue Bereich kann sich ändern
Bisher habe ich nur die Standardeinstellungen verwendet, z
plt.colorbar()
das gibt eine kontinuierliche Auswahl an Farben. Idealerweise möchte ich eine Menge von n diskreten Farben (in diesem Beispiel n = 20). Noch besser wäre es, einen Tag-Wert von 0 zu erhalten, um eine graue Farbe zu erzeugen, und 1-20, um bunt zu sein.
Ich habe einige 'Kochbuch'-Skripte gefunden, aber sie sind sehr kompliziert und ich kann nicht glauben, dass sie der richtige Weg sind, um ein scheinbar einfaches Problem zu lösen
quelle
Antworten:
Sie können ganz einfach eine benutzerdefinierte diskrete Farbleiste erstellen, indem Sie ein BoundaryNorm als Normalisierer für Ihre Streuung verwenden. Das skurrile Bit (in meiner Methode) lässt 0 als grau erscheinen.
Für Bilder verwende ich oft cmap.set_bad () und konvertiere meine Daten in ein numpy maskiertes Array. Das wäre viel einfacher, 0 grau zu machen, aber ich konnte dies nicht mit der Streuung oder der benutzerdefinierten cmap zum Laufen bringen.
Alternativ können Sie Ihre eigene cmap von Grund auf neu erstellen oder eine vorhandene vorlesen und nur einige bestimmte Einträge überschreiben.
Ich persönlich denke, dass es mit 20 verschiedenen Farben etwas schwierig ist, den spezifischen Wert zu lesen, aber das liegt natürlich bei Ihnen.
quelle
plt.colorbar.ColorbarBase
wirft Fehler. Verwenden Siempl.colorbar.ColorbarBase
N-1
incmap = mpl.colors.LinearSegmentedColormap.from_list('Custom cmap', cmaplist, cmap.N-1)
. Wenn nicht, sind die Farben nicht gleichmäßig in den Behältern verteilt und Sie haben ein Problem mit der Zaunbarriere.q=np.arange(0.0, 1.01, 0.1) cmap = mpl.cm.get_cmap('jet') cmaplist = [cmap(x) for x in q] cmap = mpl.colors.LinearSegmentedColormap.from_list('Custom cmap', cmaplist, len(q)-1) norm = mpl.colors.BoundaryNorm(q, cmap.N)
N-1
, Sie haben vielleicht Recht, aber ich kann es nicht mit meinem Beispiel wiederholen. Sie können dasLinearSegmentedColormap
(und seinN
Argument) vermeiden, indem Sie a verwendenListedColormap
. Die Dokumente haben sich seit '13 stark verbessert, siehe zum Beispiel: matplotlib.org/3.1.1/tutorials/colors/…Sie könnten diesem Beispiel folgen :
welches das folgende Bild erzeugt:
quelle
Die obigen Antworten sind gut, außer dass sie keine korrekte Platzierung der Häkchen in der Farbleiste haben. Ich mag es, wenn die Häkchen in der Mitte der Farbe sind, damit die Zuordnung von Zahl -> Farbe klarer wird. Sie können dieses Problem lösen, indem Sie die Grenzen des Matshow-Aufrufs ändern:
quelle
set_ticklabels(...)
sollte nur zur Steuerung der Etikettenformatierung verwendet werden (z. B. Dezimalzahl usw.). Wenn die Daten wirklich diskret sind, stellen Sie möglicherweise keine Probleme fest. Wenn das System Rauschen aufweist (z. B. 2 -> 1,9), führt diese inkonsistente Beschriftung zu einer irreführenden und falschen Farbleiste.Um Werte über oder unter dem Bereich der Farbkarte festzulegen, sollten Sie die Methoden
set_over
undset_under
der Farbkarte verwenden. Wenn Sie einen bestimmten Wert kennzeichnen möchten, maskieren Sie ihn (dh erstellen Sie ein maskiertes Array) und verwenden Sie dieset_bad
Methode. (Sehen Sie sich die Dokumentation für die Basis-Colormap-Klasse an: http://matplotlib.org/api/colors_api.html#matplotlib.colors.Colormap )Es hört sich so an, als ob Sie so etwas wollen:
quelle
Dieses Thema ist bereits gut behandelt, aber ich wollte etwas Spezifischeres hinzufügen: Ich wollte sichergehen, dass ein bestimmter Wert dieser Farbe zugeordnet wird (keiner Farbe).
Es ist nicht kompliziert, aber da ich einige Zeit gebraucht habe, könnte es anderen helfen, nicht so viel Zeit zu verlieren wie ich :)
quelle
pos
Ich bin nicht ganz sicher, warum es hier ist , aber es wird durch die FuncFormatter () angefordert ... Vielleicht hat jemand anderes kann uns darüber aufklären!Ich habe diese Ideen untersucht und hier sind meine fünf Cent wert. Es wird vermieden, aufzurufen
BoundaryNorm
undnorm
als Argument fürscatter
und anzugebencolorbar
. Ich habe jedoch keine Möglichkeit gefunden, den ziemlich langwierigen Anruf zu beseitigenmatplotlib.colors.LinearSegmentedColormap.from_list
.Hintergrund ist, dass matplotlib sogenannte qualitative Farbkarten bereitstellt, die mit diskreten Daten verwendet werden sollen.
Set1
hat beispielsweise 9 leicht unterscheidbare Farben undtab20
könnte für 20 Farben verwendet werden. Bei diesen Karten kann es natürlich sein, ihre ersten n Farben zu verwenden, um Streudiagramme mit n Kategorien zu färben, wie im folgenden Beispiel. Das Beispiel erzeugt auch eine Farbleiste mit n diskreten Farben, die entsprechend gekennzeichnet sind.welches das Bild unten erzeugt. Das
n
im Aufruf zum AngebenSet1
der erstenn
Farben dieser Farbkarte und das letzten
im Aufruf zum Angeben,from_list
um eine Karte mitn
Farben zu erstellen (der Standardwert ist 256). Umcm
die Standard-Farbkarte mit festzulegenplt.set_cmap
, musste ich ihr einen Namen geben und sie registrieren, nämlich:quelle
Ich denke, Sie möchten sich colours.ListedColormap ansehen , um Ihre Farbkarte zu generieren, oder wenn Sie nur eine statische Farbkarte benötigen, habe ich an einer App gearbeitet , die möglicherweise hilft.
quelle