Como desenhar linhas verticais em um determinado gráfico no matplotlib?

259

Dado um gráfico de sinal na representação do tempo, como desenhar linhas marcando o índice de tempo correspondente?

Especificamente, dado um gráfico de sinal com índice de tempo variando de 0 a 2,6 (s), quero desenhar linhas vermelhas verticais indicando o índice de tempo correspondente para a lista [0.22058956, 0.33088437, 2.20589566], como posso fazer isso?

Francis
fonte

Respostas:

424

A maneira padrão de adicionar linhas verticais que cobrem toda a janela de plotagem sem que você precise especificar a altura real é 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)

Você pode usar muitas das palavras-chave disponíveis para outros comandos lote (por exemplo color, linestyle, linewidth...). Você pode passar argumentos de palavras-chave ymine, ymaxse desejar, nos eixos se restringem (por exemplo ymin=0.25, ymax=0.75cobrirão a metade do meio do gráfico). Existem funções correspondentes para linhas horizontais ( axhline) e retângulos ( axvspan).

Gabriel
fonte
7
Mas como plotar a linha em um determinado objeto de eixo?
Eric
8
@ Eric se axé o objeto, então ax.axvline(x=0.220589956)parece funcionar para mim.
Joel
Os argumentos para axvline são escalares de 0 a 1, relativos à janela de plotagem. Como você desenha uma linha em uma determinada posição x ou y, como 2.205 ... que foi feita nesta pergunta?
Edward Ned Harvey
Parece que stackoverflow.com/questions/16930328/… tem uma resposta. plt.plot((x1,x2),(y1,y2))
Edward Ned Harvey
1
Observe que ymax e ymin devem estar entre 0 e 1, sendo 0 a parte inferior da plotagem, 1 a parte superior da plotagem. Se você estiver usando valores além desse intervalo, será necessário converter as posições y com a proporção correta.
Dylan Kapp #
50

Para várias linhas

xposition = [0.3, 0.4, 0.45]
for xc in xposition:
    plt.axvline(x=xc, color='k', linestyle='--')
Qina Yan
fonte
1
como colocamos uma legenda na linha vertical?
Charlie Parker
@CharlieParker considere fazer uma pergunta separada. Esta parte da documentação matplotlib pode ajudá-lo
Ciprian Tomoiagă
@CharlieParker uma opção extra label='label'faz o trabalho, mas você precisa chamar plt.legend([options])mais tarde
kon psych
29

Se alguém quiser adicionar um legende / ou colorsalgumas linhas verticais, use o seguinte:


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

Resultados:

meu enredo incrível seralouk

seralouk
fonte
27

Chamar axvline em um loop, como outros sugeriram, funciona, mas pode ser inconveniente porque

  1. Cada linha é um objeto de plotagem separado, o que faz com que as coisas fiquem muito lentas quando você tem muitas linhas.
  2. Quando você cria a legenda, cada linha tem uma nova entrada, que pode não ser o que você deseja.

Em vez disso, você pode usar as seguintes funções de conveniência que criam todas as linhas como um único objeto de plotagem:

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
fonte
15

Além do plt.axvlinee plt.plot((x1, x2), (y1, y2))OU, plt.plot([x1, x2], [y1, y2])conforme fornecido nas respostas acima, também é possível usar

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

para traçar uma linha vertical em x_posque mede a partir y1de y2onde os valores y1e y2estão em coordenadas absolutas de dados.

Sheldore
fonte