Hoe je verticale lijnen tekent op een gegeven plot in matplotlib

Gegeven een plot van signaal in tijdweergave, hoe teken je lijnen die de bijbehorende tijdindex markeren?

Specifiek, gezien een signaalgrafiek met een tijdindex variërend van 0 tot 2.6(s), wil ik verticale rode lijnen tekenen die de corresponderende tijdindex voor de lijst aangeven [0.22058956, 0.33088437, 2.20589566], hoe kan ik dat doen?


Antwoord 1, autoriteit 100%

De standaardmanier om verticale lijnen toe te voegen die uw hele plotvenster bedekken zonder dat u hun werkelijke hoogte hoeft op te geven, is plt.axvline

import matplotlib.pyplot as plt
plt.axvline(x=0.22058956)
plt.axvline(x=0.33088437)
plt.axvline(x=2.20589566)

OF

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

U kunt veel van de trefwoorden gebruiken die beschikbaar zijn voor andere plotcommando’s (bijv. color, linestyle, linewidth…). U kunt trefwoordargumenten yminen ymaxinvoeren als u wilt in assencordinaten (bijv. ymin=0.25, ymax=0.75zal de middelste helft van de plot beslaan). Er zijn overeenkomstige functies voor horizontale lijnen (axhline) en rechthoeken (axvspan).


Antwoord 2, autoriteit 13%

Voor meerdere lijnen

xposition = [0.3, 0.4, 0.45]
for xc in xposition:
    plt.axvline(x=xc, color='k', linestyle='--')

Antwoord 3, autoriteit 9%

Als iemand een legenden/of colorswil toevoegen aan enkele verticale lijnen, gebruik dan dit:


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()

Resultaten:


Antwoord 4, autoriteit 5%

Axvline in een lus aanroepen, zoals anderen hebben gesuggereerd, werkt, maar kan onhandig zijn omdat

  1. Elke regel is een apart plotobject, waardoor het erg traag gaat als je veel regels hebt.
  2. Als je de legenda maakt, heeft elke regel een nieuw item, wat misschien niet is wat je wilt.

In plaats daarvan kunt u de volgende gemaksfuncties gebruiken die alle lijnen als een enkel plotobject maken:

import matplotlib.pyplot as plt
import numpy as np
def axhlines(ys, ax=None, lims=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 lims: Optionally the (xmin, xmax) of the lines
    :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)
    if lims is None:
        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, lims=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 lims: Optionally the (ymin, ymax) of the lines
    :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)
    if lims is None:
        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

Antwoord 5, autoriteit 5%

matplotlib.pyplot.vlinesversus matplotlib.pyplot.axvline

  • Het verschil is dat vlines1 of meer locaties accepteert voor x, terwijl axvlineéén locatie toestaat.
    • Eén locatie: x=37
    • Meerdere locaties: x=[37, 38, 39]
  • vlinesneemt yminen ymaxals een positie op de y-as, terwijl axvlineyminen ymaxals een percentage van het bereik van de y-as.
    • Bij het passeren van meerdere regels naar vlines, geef een listtoe aan yminen ymax.
  • Als u een figuur plakt met zoiets als fig, ax = plt.subplots(), vervang dan plt.vlinesof plt.axvlineMET ax.vlinesOF ax.axvline, respectievelijk.
import numpy as np
import matplotlib.pyplot as plt
xs = np.linspace(1, 21, 200)
plt.figure(figsize=(10, 7))
# only one line may be specified; full height
plt.axvline(x=36, color='b', label='axvline - full height')
# only one line may be specified; ymin & ymax spedified as a percentage of y-range
plt.axvline(x=36.25, ymin=0.05, ymax=0.95, color='b', label='axvline - % of full height')
# multiple lines all full height
plt.vlines(x=[37, 37.25, 37.5], ymin=0, ymax=len(xs), colors='purple', ls='--', lw=2, label='vline_multiple - full height')
# multiple lines with varying ymin and ymax
plt.vlines(x=[38, 38.25, 38.5], ymin=[0, 25, 75], ymax=[200, 175, 150], colors='teal', ls='--', lw=2, label='vline_multiple - partial height')
# single vline with full ymin and ymax
plt.vlines(x=39, ymin=0, ymax=len(xs), colors='green', ls=':', lw=2, label='vline_single - full height')
# single vline with specific ymin and ymax
plt.vlines(x=39.25, ymin=25, ymax=150, colors='green', ls=':', lw=2, label='vline_single - partial height')
# place legend outside
plt.legend(bbox_to_anchor=(1.0, 1), loc='upper left')
plt.show()


Antwoord 6, Autoriteit 3%

Naast de plt.axvlineen plt.plot((x1, x2), (y1, y2))OF plt.plot([x1, x2], [y1, y2])Zoals verstrekt in de bovenstaande antwoorden, kan men ook

gebruiken

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

Om een verticale lijn op te zetten op x_posspanning van y1naar y2waarbij de waarden y1en y2zijn in absolute gegevenscoördinaten.

Other episodes