Ist es möglich, den aktuellen Status des Matplotlib-Farbzyklus abzufragen? Mit anderen Worten, gibt es eine Funktion get_cycle_state
, die sich wie folgt verhält?
>>> plot(x1, y1)
>>> plot(x2, y2)
>>> state = get_cycle_state()
>>> print state
2
Wo ich erwarte, dass der Zustand der Index der nächsten Farbe ist, die in einem Diagramm verwendet wird. Alternativ wäre es auch in Ordnung, wenn die nächste Farbe zurückgegeben würde ("r" für den Standardzyklus im obigen Beispiel).
python
matplotlib
mwaskom
quelle
quelle
Antworten:
Zugriff auf den Farbzyklus-Iterator
Es gibt keine "benutzerbezogene" (auch "öffentliche") Methode, um auf den zugrunde liegenden Iterator zuzugreifen, aber Sie können über "private" (gemäß Konvention) Methoden darauf zugreifen. Sie können den Status eines jedoch nicht erhalten,
iterator
ohne ihn zu ändern.Einstellen des Farbzyklus
Schnell beiseite: Sie können den Farb- / Eigenschaftszyklus auf verschiedene Arten einstellen (z. B.
ax.set_color_cycle
in Versionen <1.5 oderax.set_prop_cycler
in> = 1.5). Schauen Sie sich das Beispiel hier für Version 1.5 oder höher oder den vorherigen Stil hier an .Zugriff auf den zugrunde liegenden Iterator
Es gibt zwar keine öffentlich zugängliche Methode für den Zugriff auf die iterable Datei, Sie können jedoch für ein bestimmtes Achsenobjekt (
ax
) über die Hilfsklasseninstanz darauf zugreifen_get_lines
.ax._get_lines
ist eine verwirrend benannte Berührung, aber es ist die Maschinerie hinter den Kulissen, die es demplot
Befehl ermöglicht, alle seltsamen und unterschiedlichen Arten zu verarbeiten,plot
die aufgerufen werden können. Unter anderem wird verfolgt, welche Farben automatisch zugewiesen werden sollen. Ebenso können Sie dasax._get_patches_for_fill
Durchlaufen der Standardfüllfarben und Patch-Eigenschaften steuern.In jedem Fall gilt der iterierbare Farbzyklus
ax._get_lines.color_cycle
für Linien undax._get_patches_for_fill.color_cycle
Patches. Bei matplotlib> = 1.5 wurde dies geändert, um diecycler
Bibliothek zu verwenden , und die iterable wirdprop_cycler
anstelle voncolor_cycle
und ruft einedict
von Eigenschaften anstelle von nur einer Farbe auf.Alles in allem würden Sie so etwas tun wie:
Sie können den Status eines nicht anzeigen
iterator
Dieses Objekt ist jedoch "nackt"
iterator
. Wir können leicht das nächste Element erhalten (z. B.next_color = next(color_cycle)
aber das bedeutet, dass die nächste Farbe danach geplottet wird. Konstruktionsbedingt gibt es keine Möglichkeit, den aktuellen Status eines Iterators abzurufen, ohne ihn zu ändern.In
v1.5
oder höher wäre es schön, das verwendetecycler
Objekt zu erhalten , da wir auf seinen aktuellen Zustand schließen könnten. Dascycler
Objekt selbst ist jedoch nirgendwo (öffentlich oder privat) zugänglich. Stattdessen kann nur auf dieitertools.cycle
aus demcycler
Objekt erstellte Instanz zugegriffen werden. In beiden Fällen gibt es keine Möglichkeit, zum zugrunde liegenden Status des Farb- / Eigenschaftszyklers zu gelangen.Passen Sie stattdessen die Farbe des zuvor gezeichneten Elements an
In Ihrem Fall klingt es so, als ob Sie die Farbe von etwas anpassen möchten, das gerade gezeichnet wurde. Anstatt zu versuchen, die Farbe / Eigenschaft zu bestimmen, legen Sie die Farbe / usw. Ihres neuen Elements basierend auf den Eigenschaften der gezeichneten Elemente fest.
In dem von Ihnen beschriebenen Fall würde ich beispielsweise Folgendes tun:
Dies ist nicht der einzige Weg, aber in diesem Fall sauberer als der Versuch, die Farbe der gezeichneten Linie vorher zu ermitteln.
quelle
line, = ax.plot(x, y)
und dann verwendenline.get_color()
, um die Farbe der zuvor gezeichneten Linie zu erhalten.ax._get_lines.color_cycle
nicht mehr in 1.5 zu existieren?ax._get_lines.prop_cycler
Sie können ein Konstrukt haben,if 'color' in ax._get_lines._prop_keys:
gefolgt vonnext(ax._get_lines.prop_cycler)['color']
dem Äquivalent dessen, wascolor_cycle
in der Antwort vorgeschlagen wird, glaube ich. Ich bin mir nicht sicher, ob Sie nur die Farben iterieren können. Ich müsste mehr erforschen.Hier ist ein Weg, der in 1.5 funktioniert und hoffentlich zukunftssicher ist, da er nicht auf Methoden beruht, denen Unterstriche vorangestellt sind:
Dadurch erhalten Sie eine Liste der Farben, die für den aktuellen Stil definiert wurden.
quelle
Hinweis: In den neuesten Versionen von matplotlib (> = 1.5)
_get_lines
wurde geändert. Sie müssen jetztnext(ax._get_lines.prop_cycler)['color']
in Python 2 oder 3 (oderax._get_lines.prop_cycler.next()['color']
in Python 2 ) verwenden, um die nächste Farbe aus dem Farbzyklus zu erhalten.Verwenden Sie nach Möglichkeit den direkteren Ansatz, der im unteren Teil der Antwort von @ joe-kington gezeigt wird. Da
_get_lines
es sich nicht um eine API handelt, kann es sich in Zukunft möglicherweise nicht mehr abwärtskompatibel ändern.quelle
Sicher, das wird es tun.
Gibt:
Hier ist die Funktion , die itertools matplotlib Anwendungen itertools.cycle
Bearbeiten: Danke für den Kommentar, es scheint, dass es nicht möglich ist, einen Iterator zu kopieren. Eine Idee wäre, einen vollständigen Zyklus zu sichern und zu verfolgen, welchen Wert Sie verwenden. Lassen Sie mich darauf zurückkommen.
Edit2: In Ordnung, dies gibt Ihnen die nächste Farbe und erstellt einen neuen Iterator, der sich so verhält, als ob next nicht aufgerufen wurde. Dies behält nicht die Reihenfolge der Färbung bei, nur den nächsten Farbwert, das überlasse ich Ihnen.
Dies ergibt die folgende Ausgabe. Beachten Sie, dass die Steilheit im Diagramm dem Index entspricht, z. B. ist das erste g das unterste Diagramm und so weiter.
Konsole
quelle
Ich möchte nur hinzufügen, was @Andi oben gesagt hat. Da
color_cycle
es in matplotlib 1.5 veraltet ist, müssen Sieprop_cycler
jedoch verwenden. Andis Lösung (ax._get_lines.prop_cycler.next()['color']
) hat diesen Fehler für mich zurückgegeben:Der Code, der für mich funktioniert hat, war :
next(ax._get_lines.prop_cycler)
, was eigentlich nicht weit von @ joe-kingtons ursprünglicher Antwort entfernt ist.Persönlich bin ich auf dieses Problem gestoßen, als ich eine twinx () -Achse erstellt habe, die den Farbzyklus zurückgesetzt hat. Ich brauchte einen Weg, um die Farben richtig laufen zu lassen, weil ich sie benutzte
style.use('ggplot')
. Es könnte einen einfacheren / besseren Weg geben, dies zu tun. Sie können mich also gerne korrigieren.quelle
next(ax._get_lines.prop_cycler)
eine mögliche Alternative ist.next(ax._get_lines.prop_cycler)
tatsächlich den Status des Farbzyklers ändert?prop_cycler
. Wenn Sie die akzeptierte Antwort auf diese Frage lesen, werden Sie feststellen, dass es keine Möglichkeit gibt, auf den Status von zuzugreifen,prop_cycler
ohne dessen Status zu ändern, da er iterierbar ist.Da matplotlib verwendet
itertools.cycle
, können wir tatsächlich den gesamten Farbzyklus durchsehen und dann den vorherigen Zustand des Iterators wiederherstellen:Dies sollte die Liste zurückgeben, ohne den Status des Iterators zu ändern.
Verwenden Sie es mit matplotlib> = 1.5:
oder mit matplotlib <1,5:
quelle
Der einfachste Weg, den ich finden könnte, ohne die gesamte Schleife durch den Cycler zu machen, ist
ax1.lines[-1].get_color()
.quelle
In matplotlib Version 2.2.3 gibt es eine
get_next_color()
Methode für die_get_lines
Eigenschaft:get_next_color()
Gibt eine HTML-Farbzeichenfolge zurück und erweitert den Farbzyklus-Iterator.quelle
Wie greife ich auf den Farbzyklus (und den vollständigen Stilzyklus) zu?
Der aktuelle Status wird in gespeichert
ax._get_lines.prop_cycler
. Es gibt keine integrierten Methoden, um die "Basisliste" für ein Generikumitertools.cycle
und insbesondere fürax._get_lines.prop_cycler
(siehe unten) verfügbar zu machen.Ich habe hier einige Funktionen gepostet , um Informationen zu erhalten
itertools.cycle
. Man könnte dann gebrauchenum die aktuelle Farbe zu erhalten, ohne den Status des Zyklus zu ändern .
TL; DR
Wo ist der Farbzyklus (und der vollständige Stilzyklus) gespeichert?
Der Stilzyklus wird an zwei verschiedenen Stellen gespeichert, eine für die Standardachse und eine für die aktuellen Achsen (vorausgesetzt
import matplotlib.pyplot as plt
undax
ist ein Achsenhandler):Beachten Sie, dass diese unterschiedliche Klassen haben. Die Standardeinstellung ist eine "Basiszykluseinstellung" und kennt keinen aktuellen Status für Achsen, während der Strom den folgenden Zyklus und seinen aktuellen Status kennt:
Der Standardzyklus kann mehrere Schlüssel (Eigenschaften) zum Zyklisieren haben, und man kann nur die Farben erhalten:
Man könnte sogar die
cycler
Verwendung für eine gegebeneaxes
, nachdem man das definiert hatcustom_prop_cycler
, mit ändernEs gibt jedoch keine integrierten Methoden, um die "Basisliste" für ein Generikum
itertools.cycle
und insbesondere für anzuzeigenax._get_lines.prop_cycler
.quelle