如何在matplotlib中的给定图上绘制垂直线?

问题:如何在matplotlib中的给定图上绘制垂直线?

给定时间表示中的信号图,如何绘制标记相应时间索引的线?

具体来说,给定时间索引范围从0到2.6(s)的信号图,我想绘制垂直红线以指示列表的相应时间索引[0.22058956, 0.33088437, 2.20589566],我该怎么办?

Given a plot of signal in time representation, how to draw lines marking corresponding time index?

Specifically, given a signal plot with time index ranging from 0 to 2.6(s), I want to draw vertical red lines indicating corresponding time index for the list [0.22058956, 0.33088437, 2.20589566], how can I do it?


回答 0

添加覆盖整个绘图窗口的垂直线而无需指定其实际高度的标准方法是 plt.axvline

import matplotlib.pyplot as plt

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

要么

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

您可以使用许多可用于其他情节命令的关键字(例如colorlinestylelinewidth…)。您可以传递关键字参数yminymax如果愿意,可以传递坐标(例如ymin=0.25ymax=0.75将覆盖图的中部)。水平线(axhline)和矩形(axvspan)有相应的功能。

The standard way to add vertical lines that will cover your entire plot window without you having to specify their actual height is plt.axvline

import matplotlib.pyplot as plt

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

OR

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

You can use many of the keywords available for other plot commands (e.g. color, linestyle, linewidth …). You can pass in keyword arguments ymin and ymax if you like in axes corrdinates (e.g. ymin=0.25, ymax=0.75 will cover the middle half of the plot). There are corresponding functions for horizontal lines (axhline) and rectangles (axvspan).


回答 1

多行

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

For multiple lines

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

回答 2

如果有人想在垂直线上添加legend和/或colors,请使用以下命令:


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

结果:

If someone wants to add a legend and/or colors to some vertical lines, then use this:


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

Results:


回答 3

正如其他人所建议的那样,以循环方式调用axvline是可行的,但是由于不方便,

  1. 每行是一个单独的绘图对象,当您有多行时,这会使事情变得很慢。
  2. 创建图例时,每行都有一个新条目,可能不是您想要的。

相反,您可以使用以下便利功能,这些功能将所有线创建为一个绘图对象:

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

Calling axvline in a loop, as others have suggested, works, but can be inconvenient because

  1. Each line is a separate plot object, which causes things to be very slow when you have many lines.
  2. When you create the legend each line has a new entry, which may not be what you want.

Instead you can use the following convenience functions which create all the lines as a single plot object:

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

回答 4

除了plt.axvlineplt.plot((x1, x2), (y1, y2))OR plt.plot([x1, x2], [y1, y2])中的答案的上方设置,还可以使用

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

绘制一条x_posy1y2的值y1y2在绝对数据坐标中的位置的垂直线。

In addition to the plt.axvline and plt.plot((x1, x2), (y1, y2)) OR plt.plot([x1, x2], [y1, y2]) as provided in the answers above, one can also use

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

to plot a vertical line at x_pos spanning from y1 to y2 where the values y1 and y2 are in absolute data coordinates.