HOWTO · Matplotlib

Wie man in Matplotlib Streudiagrammpunkte mit Linien verbindet

Verbinden Sie Matplotlib-Streudiagrammpunkte in Datenreihenfolge mit `plot()`, gestalten Sie die Linie und steuern Sie mit `zorder`, welche Ebene oben erscheint.

Auf dieser Seite

Um Streudiagrammpunkte in ihrer Datenreihenfolge zu verbinden, übergib dieselben x- und y-Werte an scatter() und plot() und rufe anschließend show() auf, um die Abbildung anzuzeigen. scatter() zeichnet die Markierungen als eigenständige Sammlung, plot() zeichnet den Verbindungspfad durch die Punkte in der angegebenen Reihenfolge, und show() zeigt die fertige Abbildung an.

Die Beispiele in diesem Tutorial wurden mit Matplotlib 3.11.2 unter Python 3.12 ausgeführt und überprüft, und jede Abbildung unten ist das gerenderte Ergebnis des Beispiels direkt darüber.

Streudiagrammpunkte mit scatter() und plot() in Datenreihenfolge verbinden

Übergib beiden Funktionen dieselben Koordinatenfolgen. plot() verbindet die einzelnen Paare in der angegebenen Reihenfolge; die Reihenfolge bestimmt also den Pfad, denn Matplotlib sortiert die Punkte nicht nach ihrer x-Koordinate. Achte darauf, dass jeder x-Wert seinem zugehörigen y-Wert zugeordnet bleibt: Der erste x-Wert gehört zum ersten y-Wert, der zweite zum zweiten und so weiter. Wenn du die Beobachtungen nach x sortierst, ordne die y-Werte zusammen mit denselben Beobachtungen neu an, statt beide Listen unabhängig voneinander zu sortieren.

Das ist wichtig, wenn die Daten eine Route, eine Zeitreihe oder eine andere Sequenz darstellen, bei der die Reihenfolge eine Bedeutung hat. Steigen die x-Werte beispielsweise von 1 auf 3 und fallen dann auf 2 zurück, verläuft der Pfad erst nach rechts und dann nach links. Bei einer Trajektorie kann das genau richtig sein. Soll die Kurve stattdessen von links nach rechts verlaufen, sortiere zuerst die zusammengehörigen Beobachtungen. Haben benachbarte Beobachtungen denselben x-Wert, kann die Linie auch vertikale Abschnitte enthalten; plot() verbindet sie weiterhin in der angegebenen Reihenfolge.

Dieses Beispiel legt Markierungen und Verbindungslinie anhand derselben Koordinaten übereinander:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [2, 1, 3, 2]

plt.scatter(x, y)
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("y")
plt.show()

Vier Streudiagrammpunkte bei (1, 2), (2, 1), (3, 3) und (4, 2), in Datenreihenfolge durch eine durchgezogene Linie verbunden.

Dieselben x- und y-Eingaben halten Markierungen und Linie aufeinander ausgerichtet. Wirken die beiden Ebenen gegeneinander verschoben, prüfe, ob eine der Folgen nur für einen der beiden Aufrufe transformiert oder neu geordnet wurde. Bei Daten aus einer Tabelle wähle beide Spalten aus denselben Zeilen und in derselben Reihenfolge aus. Das Beispiel verwendet die pyplot-Schnittstelle und braucht daher keine separate Figure-Variable; bei der objektorientierten Schnittstelle erzeugst du mit fig, ax = plt.subplots() eine Figure und Achsen und rufst dann ax.scatter(...) und ax.plot(...) auf diesen Achsen auf.

Linie und Markierungen mit plot() gestalten

Verwende linestyle und color, um den von plot() gezeichneten Pfad zu gestalten. Das nächste Beispiel behält eine separate scatter()-Ebene für die Markierungen und zeichnet den Verbindungspfad als gestrichelte blaue Linie:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [2, 1, 3, 2]

plt.scatter(x, y, color="blue")
plt.plot(x, y, linestyle="--", color="blue")
plt.xlabel("x")
plt.ylabel("y")
plt.show()

Dieselben vier Punkte, verbunden durch eine blaue gestrichelte Linie, mit einer blauen Markierung an jedem Punkt.

scatter() und plot() getrennt aufzurufen gibt dir unabhängige Kontrolle über die Punktsammlung und den Verbindungspfad: Markierungsgröße und -farbe lassen sich ändern, ohne die Linie zu berühren – nützlich, wenn die Punkte stärker betont werden sollen, während der Pfad visuell schlicht bleibt. Übergib beiden Aufrufen dieselben Koordinatenfolgen, damit jede Markierung auf ihrem entsprechenden Punkt in der Linie sitzt.

Ein einzelner plot()-Aufruf kann auch beide Ebenen auf einmal zeichnen, über eine Formatzeichenkette wie "xb-", wobei x die Markierungsform, b Blau und - eine durchgezogene Linie auswählt. Die Formatzeichenkette ist kompakt, wenn ein Aufruf alles zeichnen soll; Schlüsselwortargumente wie color, marker und linestyle sind klarer, wenn du weitere Eigenschaften wie Markierungsgröße, Linienbreite oder Transparenz brauchst. Für welche Vorgehensweise du dich auch entscheidest: show() gehört hinter alle Gestaltungs- und Ebenenaufrufe, weil es die Abbildung erst anzeigt, nachdem diese Elemente hinzugefügt wurden.

Mit zorder steuern, welche Ebene oben erscheint

Das Element mit dem höheren zorder wird über dem mit dem niedrigeren Wert gezeichnet. Das ändert nur die Zeichenreihenfolge, nicht die Koordinaten oder den Pfad. Die Einstellung ist wichtig, wenn eine dicke Linie eine Markierung kreuzt und ihre Mitte verdeckt, oder wenn die Linie über dichten Markierungen sichtbar bleiben soll.

Das nächste Beispiel macht die Linie absichtlich dick und gibt den Markierungen den höheren zorder, sodass jede runde Markierung dort ganz bleibt, wo die Linie unter ihr hindurchläuft:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [2, 1, 3, 2]

plt.plot(x, y, linewidth=6, zorder=2)
plt.scatter(x, y, s=120, zorder=3)
plt.xlabel("x")
plt.ylabel("y")
plt.show()

Eine dicke Linie durch die vier Punkte, mit größeren runden Markierungen, die an jedem Punkt auf der Linie gezeichnet sind.

Damit die Markierungen über der Linie liegen, gib der Scatter-Sammlung den größeren Wert, wie oben zorder=3 für scatter() gegenüber zorder=2 für plot(). Um die Linie über die Markierungen zu legen, tausche die Werte. Wähle einen bescheidenen Unterschied zwischen den beiden Werten, um die beabsichtigte Reihenfolge auszudrücken, und setze zorder bei beiden Elementen, wenn die Schichtung eindeutig sein soll. Derselbe Vergleich gilt für alle weiteren Diagrammelemente, die du später hinzufügst: Das Element mit dem höheren zorder wird über die anderen gezeichnet.

Die Längen von x und y angleichen, um den Größenfehler zu vermeiden

Beide Funktionen paaren die Werte Position für Position, daher müssen die beiden Folgen gleich lang sein. Sind sie es nicht, löst der Aufruf einen ValueError aus und es wird keine Abbildung gezeichnet. In diesem Beispiel fehlt versehentlich der letzte y-Wert:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [2, 1, 3]

plt.scatter(x, y)
plt.plot(x, y)
plt.show()

Die Ausführung scheitert beim scatter()-Aufruf mit:

ValueError: x and y must be the same size

Auch ein alleiniger plot()-Aufruf mit denselben Eingaben scheitert, mit seiner eigenen Formulierung desselben Problems: ValueError: x and y must have same first dimension, but have shapes (4,) and (3,). Um den Fehler zu beheben, finde die fehlende oder überzählige Beobachtung und bringe die beiden Folgen wieder dazu, dieselben Punkte zu beschreiben. Ein Vergleich von len(x) und len(y) vor dem Zeichnen zeigt, welche Seite zu kurz ist. Stammen die Daten aus einer Tabelle, filtere die Zeilen einmal und nimm dann beide Spalten aus den gefilterten Zeilen, statt jede Spalte einzeln zu filtern und ihre Längen auseinanderlaufen zu lassen.

Zwei leere Folgen sind ein anderer Fall: Sie werden akzeptiert und erzeugen ein leeres Achsenkreuz ohne Fehler. Eine leere Abbildung bedeutet daher meist, dass die Eingabedaten leer waren, und nicht, dass die Längen nicht übereinstimmten.