给定一个信号的时间表示图,我如何画出相应的时间索引线?

具体来说,给定一个时间指数范围为0到2.6(秒)的信号图,我想绘制垂直红线,指示列表的相应时间指数[0.22058956,0.33088437,2.20589566]。我该怎么做呢?


添加覆盖整个绘图窗口的垂直线而无需指定实际高度的标准方法是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)

你可以使用许多可用于其他绘图命令的关键字(例如颜色、线型、线宽……)。如果你喜欢轴坐标,你可以传入关键字参数ymin和ymax(例如ymin=0.25, ymax=0.75将覆盖图的中间部分)。水平线(axhline)和矩形(axvspan)有相应的函数。


对于多行

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

正如其他人建议的那样,在循环中调用axvline是可行的,但它可能不方便,因为

每一行都是一个单独的plot对象,当你有很多行时,这会导致事情非常缓慢。 当您创建图例时,每一行都有一个新的条目,这可能不是您想要的。

相反,你可以使用以下方便的函数来创建所有的线作为一个单一的绘图对象:

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

为一些垂直线添加图例和/或颜色,然后使用这个:

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

结果


除了plt。轴线和plt。Plot ((x1, x2), (y1, y2))或plt。Plot ([x1, x2], [y1, y2]),也可以使用

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

在x_pos处画一条从y1到y2的垂直线,其中y1和y2的值在绝对数据坐标中。


Matplotlib.pyplot.vlines vs. matplotlib.pyplot.axvline

These methods are applicable to plots generated with seaborn and pandas.DataFrame.plot, which both use matplotlib. The difference is that vlines accepts one or more locations for x, while axvline permits one location. Single location: x=37. Multiple locations: x=[37, 38, 39]. vlines takes ymin and ymax as a position on the y-axis, while axvline takes ymin and ymax as a percentage of the y-axis range. When passing multiple lines to vlines, pass a list to ymin and ymax. Also matplotlib.axes.Axes.vlines and matplotlib.axes.Axes.axvline for the object-oriented API. If you're plotting a figure with something like fig, ax = plt.subplots(), then replace plt.vlines or plt.axvline with ax.vlines or ax.axvline, respectively. See this answer for horizontal lines with .hlines.

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 specified 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 the legend outside
plt.legend(bbox_to_anchor=(1.0, 1), loc='upper left')

plt.show()

海博恩斧级地块

import seaborn as sns

# sample data
fmri = sns.load_dataset("fmri")

# x index for max y values for stim and cue
c_max, s_max = fmri.pivot_table(index='timepoint', columns='event', values='signal', aggfunc='mean').idxmax()

# plot
g = sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event")

# y min and max
ymin, ymax = g.get_ylim()

# vertical lines
g.vlines(x=[c_max, s_max], ymin=ymin, ymax=ymax, colors=['tab:orange', 'tab:blue'], ls='--', lw=2)

Seaborn数字级图

必须遍历每个轴。

import seaborn as sns

# sample data
fmri = sns.load_dataset("fmri")

# used to get the index values (x) for max y for each event in each region
fpt = fmri.pivot_table(index=['region', 'timepoint'], columns='event', values='signal', aggfunc='mean')

# plot
g = sns.relplot(data=fmri, x="timepoint", y="signal", col="region", hue="event", kind="line")

# iterate through the axes
for ax in g.axes.flat:
    # get y min and max
    ymin, ymax = ax.get_ylim()
    # extract the region from the title for use in selecting the index of fpt
    region = ax.get_title().split(' = ')[1]
    # get x values for max event
    c_max, s_max = fpt.loc[region].idxmax()
    # add vertical lines
    ax.vlines(x=[c_max, s_max], ymin=ymin, ymax=ymax, colors=['tab:orange', 'tab:blue'], ls='--', lw=2, alpha=0.5)

对于“region = front”,两个事件的最大值都出现在5。

Barplot和histogram

请注意,条形图标记位置具有从零开始的索引,无论轴标记标签如何,因此根据条形图索引而不是标记标签选择x。 Ax.get_xticklabels()将显示位置和标签。

import pandas as pd
import seaborn as sns

# load data
tips = sns.load_dataset('tips')

# histogram
ax = tips.plot(kind='hist', y='total_bill', bins=30, ec='k', title='Histogram with Vertical Line')
_ = ax.vlines(x=16.5, ymin=0, ymax=30, colors='r')

# barplot
ax = tips.loc[5:25, ['total_bill', 'tip']].plot(kind='bar', figsize=(15, 4), title='Barplot with Vertical Lines', rot=0)
_ = ax.vlines(x=[0, 17], ymin=0, ymax=45, colors='r')

时间序列轴

dataframe中作为x轴的日期必须是datetime dtype。如果列或索引的类型不正确,则必须使用pd.to_datetime进行转换。 如果正在使用日期数组或日期列表,请分别参考将numpy字符串数组转换为datetime或将datetime列表转换为date python。 X将接受像'2020-09-24'或datetime(2020,9,2)这样的日期。

import pandas_datareader as web  # conda or pip install this; not part of pandas
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

# get test data; this data is downloaded with the Date column in the index as a datetime dtype
df = web.DataReader('^gspc', data_source='yahoo', start='2020-09-01', end='2020-09-28').iloc[:, :2]

# display(df.head(2))
                   High          Low
Date                                
2020-09-01  3528.030029  3494.600098
2020-09-02  3588.110107  3535.229980

# plot dataframe; the index is a datetime index
ax = df.plot(figsize=(9, 6), title='S&P 500', ylabel='Price')

# add vertical lines
ax.vlines(x=[datetime(2020, 9, 2), '2020-09-24'], ymin=3200, ymax=3600, color='r', label='test lines')

ax.legend(bbox_to_anchor=(1, 1), loc='upper left')
plt.show()