Wie zeichne ich vertikale Linien auf einem bestimmten Plot in matplotlib?

259

Wie zeichnet man bei einer Darstellung des Signals in der Zeitdarstellung Linien, die den entsprechenden Zeitindex markieren?

Insbesondere möchte ich bei einem Signaldiagramm mit einem Zeitindex von 0 bis 2,6 (s) vertikale rote Linien zeichnen, die den entsprechenden Zeitindex für die Liste angeben. [0.22058956, 0.33088437, 2.20589566]Wie kann ich das tun?

Francis
quelle

Antworten:

423

Die Standardmethode zum Hinzufügen vertikaler Linien, die Ihr gesamtes Plotfenster abdecken, ohne dass Sie deren tatsächliche Höhe angeben müssen, ist plt.axvline

import matplotlib.pyplot as plt

plt.axvline(x=0.22058956)
plt.axvline(x=0.33088437)
plt.axvline(x=2.20589566)

ODER

xcoords = [0.22058956, 0.33088437, 2.20589566]
for xc in xcoords:
    plt.axvline(x=xc)

Sie können für andere Plot - Befehle zur Verfügung viele der Schlüsselwörter (zB color, linestyle, linewidth...). Sie können Schlüsselwortargumente übergeben yminund ymaxwenn Sie möchten ymin=0.25, in Achsen korridieren (z. B. ymax=0.75wird die mittlere Hälfte des Diagramms abgedeckt). Es gibt entsprechende Funktionen für horizontale Linien ( axhline) und Rechtecke ( axvspan).

Gabriel
quelle
7
Aber wie zeichne ich die Linie auf einem bestimmten Achsenobjekt?
Eric
8
@ Eric wenn axdas Objekt ist, dann ax.axvline(x=0.220589956)scheint es für mich zu funktionieren.
Joel
Die Argumente für axvline sind relativ zum Plotfenster von 0 bis 1 skalar. Wie zeichnet man eine Linie an einer bestimmten x- oder y-Position, z. B. 2.205 ... die in dieser Frage gestellt wurde?
Edward Ned Harvey
Es sieht so aus, als hätte stackoverflow.com/questions/16930328/… eine Antwort. plt.plot((x1,x2),(y1,y2))
Edward Ned Harvey
1
Bitte beachten Sie, dass ymax und ymin zwischen 0 und 1 liegen sollten, wobei 0 der untere Rand des Diagramms und 1 der obere Rand des Diagramms ist. Wenn Sie Werte außerhalb dieses Bereichs verwenden, müssen Sie die y-Positionen mit dem richtigen Verhältnis übersetzen.
Dylan Kapp
50

Für mehrere Zeilen

xposition = [0.3, 0.4, 0.45]
for xc in xposition:
    plt.axvline(x=xc, color='k', linestyle='--')
Qina Yan
quelle
1
Wie setzen wir eine Legende auf die vertikale Linie?
Charlie Parker
@CharlieParker erwägen, eine separate Frage zu stellen. Dieser Teil der Matplotlib-Dokumentation kann Ihnen helfen
Ciprian Tomoiagă
@CharlieParker Eine zusätzliche Option label='label'erledigt die Arbeit, aber Sie müssen plt.legend([options])später anrufen
kon psych
29

Wenn jemand ein legendund / oder colorseinige vertikale Linien hinzufügen möchte, verwenden Sie Folgendes :


import matplotlib.pyplot as plt

# x coordinates for the lines
xcoords = [0.1, 0.3, 0.5]
# colors for the lines
colors = ['r','k','b']

for xc,c in zip(xcoords,colors):
    plt.axvline(x=xc, label='line at x = {}'.format(xc), c=c)

plt.legend()
plt.show()

Ergebnisse:

meine erstaunliche Handlung Seralouk

Seralouk
quelle
27

Das Aufrufen von axvline in einer Schleife, wie andere vorgeschlagen haben, funktioniert, kann aber deshalb unpraktisch sein

  1. Jede Linie ist ein separates Plotobjekt, was dazu führt, dass die Dinge sehr langsam sind, wenn Sie viele Linien haben.
  2. Wenn Sie die Legende erstellen, hat jede Zeile einen neuen Eintrag, der möglicherweise nicht Ihren Wünschen entspricht.

Stattdessen können Sie die folgenden praktischen Funktionen verwenden, mit denen alle Linien als ein einziges Plotobjekt erstellt werden:

import matplotlib.pyplot as plt
import numpy as np


def axhlines(ys, ax=None, **plot_kwargs):
    """
    Draw horizontal lines across plot
    :param ys: A scalar, list, or 1D array of vertical offsets
    :param ax: The axis (or none to use gca)
    :param plot_kwargs: Keyword arguments to be passed to plot
    :return: The plot object corresponding to the lines.
    """
    if ax is None:
        ax = plt.gca()
    ys = np.array((ys, ) if np.isscalar(ys) else ys, copy=False)
    lims = ax.get_xlim()
    y_points = np.repeat(ys[:, None], repeats=3, axis=1).flatten()
    x_points = np.repeat(np.array(lims + (np.nan, ))[None, :], repeats=len(ys), axis=0).flatten()
    plot = ax.plot(x_points, y_points, scalex = False, **plot_kwargs)
    return plot


def axvlines(xs, ax=None, **plot_kwargs):
    """
    Draw vertical lines on plot
    :param xs: A scalar, list, or 1D array of horizontal offsets
    :param ax: The axis (or none to use gca)
    :param plot_kwargs: Keyword arguments to be passed to plot
    :return: The plot object corresponding to the lines.
    """
    if ax is None:
        ax = plt.gca()
    xs = np.array((xs, ) if np.isscalar(xs) else xs, copy=False)
    lims = ax.get_ylim()
    x_points = np.repeat(xs[:, None], repeats=3, axis=1).flatten()
    y_points = np.repeat(np.array(lims + (np.nan, ))[None, :], repeats=len(xs), axis=0).flatten()
    plot = ax.plot(x_points, y_points, scaley = False, **plot_kwargs)
    return plot
Peter
quelle
15

Zusätzlich zu plt.axvlineund und plt.plot((x1, x2), (y1, y2))OR, plt.plot([x1, x2], [y1, y2])wie in den obigen Antworten angegeben, kann man auch verwenden

plt.vlines(x_pos, ymin=y1, ymax=y2)

um eine vertikale Linie zu zeichnen, x_posdie sich von y1bis zu y2den Werten erstreckt y1und y2in absoluten Datenkoordinaten liegt.

Sheldore
quelle