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

Fra*_*cis 220 python matplotlib

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

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

Gab*_*iel 364

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

import matplotlib.pyplot as plt

plt.axvline(x=0.22058956)
plt.axvline(x=0.33088437)
plt.axvline(x=2.20589566)
Run Code Online (Sandbox Code Playgroud)

要么

xcoords = [0.22058956, 0.33088437, 2.20589566]
for xc in xcoords:
    plt.axvline(x=xc)
Run Code Online (Sandbox Code Playgroud)

您可以使用许多可用于其他情节命令的关键字(例如color,linestyle,linewidth...).您可以传递关键字参数ymin,ymax如果您喜欢轴corrdinates(例如ymin=0.25,ymax=0.75将覆盖图的中间一半).水平线(axhline)和矩形(axvspan)有相应的功能.

  • 但是如何绘制给定轴对象上的线? (7认同)
  • @Eric如果`ax`是对象,那么`ax.axvline(x = 0.220589956)`似乎适合我. (7认同)

小智 41

对于多行

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


Tre*_*ney 32

matplotlib.pyplot.vlines 对比 matplotlib.pyplot.axvline

  • 不同之处在于vlines接受 1 个或多个位置x,而axvline允许 1 个位置。
    • 单一地点: x=37
    • 多个地点: x=[37, 38, 39]
  • vlinesyminandymax作为 y 轴上的位置,而axvlineyminandymax作为 y 轴范围的百分比。
    • 将多行传递给 时vlines,传递listyminymax
  • 如果您要使用类似的内容绘制图形fig, ax = plt.subplots(),则分别将plt.vlines或替换plt.axvlineax.vlinesax.axvline
  • 请参阅此答案以了解水平线.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 legend outside
plt.legend(bbox_to_anchor=(1.0, 1), loc='upper left')

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

条形图和直方图

  • 请注意,无论轴标签如何,条形图通常都是 0 索引的,因此请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')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在此处输入图片说明

时间序列轴

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())
                   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 line
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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


Pet*_*ter 25

正如其他人所建议的那样,在循环中调用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
Run Code Online (Sandbox Code Playgroud)


mak*_*kis 18

如果有人想要添加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()
Run Code Online (Sandbox Code Playgroud)

结果:

我惊人的情节seralouk


She*_*ore 10

除了上面的答案中提供的plt.axvlineplt.plot((x1, x2), (y1, y2))OR plt.plot([x1, x2], [y1, y2])之外,还可以使用

plt.vlines(x_pos, ymin=y1, ymax=y2)
Run Code Online (Sandbox Code Playgroud)

绘制x_pos从跨越y1y2值的垂直线,y1y2在绝对数据坐标中.