plotting
data visualization
vertical lines
matplotlib
graph enhancement

How to draw vertical lines on a given plot

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Vertical lines are one of the easiest ways to mark thresholds, timestamps, releases, or anomalies on a chart. In Matplotlib, the main choice is between axvline, which spans the axes by default, and vlines, which lets you control the start and end in data coordinates.

Use axvline for a single full-height marker

If you want one line that marks a specific x-value across the plot area, axvline is the simplest tool.

python
1import matplotlib.pyplot as plt
2import numpy as np
3
4x = np.arange(0, 10, 0.1)
5y = np.sin(x)
6
7fig, ax = plt.subplots()
8ax.plot(x, y, label="sin(x)")
9ax.axvline(x=3.14, color="crimson", linestyle="--", linewidth=2, label="pi")
10ax.legend()
11plt.show()

The x-position is in data coordinates, but the height is expressed relative to the axis. That means the line stays aligned correctly even if you later change the y-limits.

If you want the line to cover only part of the plotting area, use ymin and ymax with values between 0 and 1:

python
ax.axvline(x=3.14, ymin=0.25, ymax=0.75, color="black")

Use vlines when you need multiple markers

When you want several vertical markers at once, vlines is often more convenient. It also uses explicit y-data values for the start and end of each line.

python
1import matplotlib.pyplot as plt
2
3days = [1, 2, 3, 4, 5, 6]
4sales = [10, 12, 9, 15, 14, 18]
5release_days = [2, 5]
6
7fig, ax = plt.subplots()
8ax.plot(days, sales, marker="o")
9ax.vlines(
10    release_days,
11    ymin=min(sales),
12    ymax=max(sales),
13    colors="steelblue",
14    linestyles="dotted",
15    linewidth=2,
16)
17plt.show()

This is useful for repeated events such as deployments, experiment boundaries, or sensor alerts.

Datetime plots work the same way

You can also place vertical lines on time-based plots. The key is to use parsed date values rather than raw strings.

python
1import matplotlib.pyplot as plt
2import pandas as pd
3
4dates = pd.date_range("2026-01-01", periods=5)
5values = [4, 6, 5, 9, 8]
6
7fig, ax = plt.subplots()
8ax.plot(dates, values)
9ax.axvline(pd.Timestamp("2026-01-03"), color="orange", linewidth=2)
10fig.autofmt_xdate()
11plt.show()

Matplotlib will handle the date axis correctly as long as the x-value is a real date or timestamp object.

Label the line so readers know why it exists

A vertical line without context can look like a rendering artifact. In practice, a short label or annotation makes the plot much easier to read.

python
1import matplotlib.pyplot as plt
2import numpy as np
3
4x = np.linspace(0, 20, 200)
5y = np.cos(x / 2)
6
7fig, ax = plt.subplots()
8ax.plot(x, y)
9ax.axvline(12, color="red", linestyle="--")
10ax.annotate(
11    "Threshold crossed",
12    xy=(12, 0.2),
13    xytext=(13, 0.8),
14    arrowprops=dict(arrowstyle="->", color="red"),
15)
16plt.show()

On dashboards, a legend label is often enough. On one-off explanatory plots, annotations are usually clearer.

Common Pitfalls

  • Mixing up axvline and vlines and then wondering why the line height behaves differently.
  • Passing ymin and ymax to axvline as if they were real data values instead of axis-relative fractions.
  • Drawing markers before the rest of the plot is finalized and then misplacing annotations after axis changes.
  • Using raw date strings instead of parsed timestamps on datetime axes.
  • Adding the same legend label inside a loop and cluttering the legend with duplicate entries.

Summary

  • Use axvline for a simple vertical marker at one x-value.
  • Use vlines when you need several lines or explicit y-data bounds.
  • Datetime plots work well as long as the x-values are real date objects.
  • Add labels or annotations so the line has clear meaning.
  • If the marker looks wrong, first check whether you used axis-relative or data coordinates.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.