Comment dessiner des lignes verticales sur une parcelle donnée dans matplotlib?

259

Étant donné un tracé du signal dans la représentation temporelle, comment tracer des lignes marquant l'indice de temps correspondant?

Plus précisément, étant donné un tracé de signal avec un indice de temps allant de 0 à 2,6 (s), je veux tracer des lignes rouges verticales indiquant l'indice de temps correspondant pour la liste [0.22058956, 0.33088437, 2.20589566], comment puis-je le faire?

Francis
la source

Réponses:

424

La manière standard d'ajouter des lignes verticales qui couvriront l'intégralité de votre fenêtre de tracé sans que vous ayez à spécifier leur hauteur réelle est plt.axvline

import matplotlib.pyplot as plt

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

OU

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

Vous pouvez utiliser plusieurs des mots - clés disponibles pour d' autres commandes de terrain (par exemple color, linestyle, linewidth...). Vous pouvez passer des arguments de mots-clés yminet ymaxsi vous le souhaitez dans les axes corrdinates (par exemple ymin=0.25, ymax=0.75couvrira la moitié centrale de l'intrigue). Il existe des fonctions correspondantes pour les lignes horizontales ( axhline) et les rectangles ( axvspan).

Gabriel
la source
7
Mais comment tracer la ligne sur un objet d'axe donné?
Eric
8
@Eric axest l'objet, ax.axvline(x=0.220589956)semble alors fonctionner pour moi.
Joel
Les arguments pour axvline sont scalaires de 0 à 1, par rapport à la fenêtre de tracé. Comment tracez-vous une ligne à une position x ou y donnée, telle que 2,205 ... qui a été posée dans cette question?
Edward Ned Harvey
On dirait que stackoverflow.com/questions/16930328/… a une réponse. plt.plot((x1,x2),(y1,y2))
Edward Ned Harvey
1
Veuillez noter que ymax et ymin doivent être compris entre 0 et 1, 0 étant le bas du graphique, 1 le haut du graphique. Si vous utilisez des valeurs au-delà de cette plage, vous devrez traduire les positions y avec le rapport correct.
Dylan Kapp
50

Pour plusieurs lignes

xposition = [0.3, 0.4, 0.45]
for xc in xposition:
    plt.axvline(x=xc, color='k', linestyle='--')
Qina Yan
la source
1
comment mettre une légende sur la ligne verticale?
Charlie Parker
@CharlieParker envisagez de poser une question distincte. Cette partie de la documentation de matplotlib peut vous aider
Ciprian Tomoiagă
@CharlieParker Une option supplémentaire label='label'fait le travail mais vous devez appeler plt.legend([options])plus tard
kon psych
29

Si quelqu'un veut ajouter un legendet / ou colorsà certaines lignes verticales, utilisez ceci:


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

Résultats:

mon incroyable intrigue seralouk

seralouk
la source
27

Appeler axvline en boucle, comme d'autres l'ont suggéré, fonctionne, mais peut être gênant car

  1. Chaque ligne est un objet de tracé distinct, ce qui ralentit considérablement les choses lorsque vous avez plusieurs lignes.
  2. Lorsque vous créez la légende, chaque ligne a une nouvelle entrée, qui peut ne pas être celle que vous souhaitez.

Au lieu de cela, vous pouvez utiliser les fonctions de commodité suivantes qui créent toutes les lignes comme un seul objet de tracé:

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
la source
15

En plus du plt.axvlineet plt.plot((x1, x2), (y1, y2))OU plt.plot([x1, x2], [y1, y2])comme indiqué dans les réponses ci-dessus, on peut également utiliser

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

pour tracer une ligne verticale au niveau x_posallant de y1à , y2où les valeurs y1et y2sont en coordonnées de données absolues.

Sheldore
la source