Come disegnare linee verticali su un dato diagramma in matplotlib?


259

Dato un diagramma del segnale nella rappresentazione del tempo, come disegnare linee che segnano l'indice temporale corrispondente?

In particolare, dato un diagramma di segnale con un indice temporale compreso tra 0 e 2,6 (s), desidero tracciare linee rosse verticali che indicano un indice temporale corrispondente per l'elenco [0.22058956, 0.33088437, 2.20589566], come posso fare?

Risposte:


424

Il modo standard per aggiungere linee verticali che copriranno l'intera finestra del diagramma senza che tu debba specificare la loro altezza effettiva è plt.axvline

import matplotlib.pyplot as plt

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

O

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

È possibile utilizzare molte delle parole chiave disponibili per altri comandi trama (ad esempio color, linestyle, linewidth...). Puoi passare gli argomenti delle parole chiave ymine, ymaxse ti piace, gli assi corrdinati (ad esempio ymin=0.25, ymax=0.75copriranno la metà centrale della trama). Esistono funzioni corrispondenti per linee orizzontali ( axhline) e rettangoli ( axvspan).


7
Ma come posso tracciare la linea su un determinato oggetto asse?
Eric

8
@Eric se axè l'oggetto, allora ax.axvline(x=0.220589956)sembra funzionare per me.
Joel

Gli argomenti per axvline sono scalari da 0 a 1, rispetto alla finestra del diagramma. Come si disegna una linea in una determinata posizione x o y, come ad esempio 2.205 ... che è stata posta in questa domanda?
Edward Ned Harvey,

Sembra che stackoverflow.com/questions/16930328/… abbia una risposta. plt.plot((x1,x2),(y1,y2))
Edward Ned Harvey,

1
Nota: ymax e ymin devono essere compresi tra 0 e 1, dove 0 è la parte inferiore della trama, 1 la parte superiore della trama. Se si utilizzano valori oltre questo intervallo, sarà necessario tradurre le posizioni y con il rapporto corretto.
Dylan Kapp,


29

Se qualcuno vuole aggiungere un legende / o colorsalcune linee verticali, usa questo:


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

risultati:

la mia fantastica trama seralouk


27

Chiamare axvline in un ciclo, come altri hanno suggerito, funziona, ma può essere scomodo perché

  1. Ogni linea è un oggetto grafico separato, che rende le cose molto lente quando si hanno molte linee.
  2. Quando crei la legenda ogni riga ha una nuova voce, che potrebbe non essere quella che desideri.

Invece puoi usare le seguenti funzioni di convenienza che creano tutte le linee come un singolo oggetto grafico:

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

15

Oltre a plt.axvlinee plt.plot((x1, x2), (y1, y2))OR plt.plot([x1, x2], [y1, y2])come indicato nelle risposte sopra, si può anche usare

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

per tracciare una linea verticale x_posche va dal y1verso y2in cui i valori y1e y2sono in coordinate assolute dati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.