python – How to draw vertical lines on a given plot in matplotlib

python – How to draw vertical lines on a given plot in matplotlib

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



xcoords = [0.22058956, 0.33088437, 2.20589566]
for xc in xcoords:

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

For multiple lines

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

python – How to draw vertical lines on a given plot in matplotlib

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

  • The difference is that vlines accepts 1 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.
  • If youre 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 legend outside
plt.legend(bbox_to_anchor=(1.0, 1), loc=upper left)


Barplot and Histograms

  • Note that barplots are usually 0 indexed, regardless of the axis labels, so select x based on the bar index, not the tick label.
    • ax.get_xticklabels() will show the locations and labels.
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)



Time Series Axis

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


Leave a Reply

Your email address will not be published. Required fields are marked *