Stem, Step & Stair Plots

Stem, step, and stair plots are Matplotlib chart types for discrete data — drawing vertical spikes, flat staircases, and histogram-style outlines that show values which exist only at specific points or hold steady between changes.

Learn Stem, Step & Stair Plots in our free Matplotlib course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Matplotlib course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll draw a stem plot for a sampled signal, build staircases with ax.step() and drawstyle, and outline histogram-shaped data with ax.stairs().

A stem plot draws a vertical line from a baseline up to each value, topped with a marker. It's the go-to for discrete data — samples that live at specific x positions. Call ax.stem(x, y) . You can style the markers and stems through the objects it returns, or just accept the clean defaults.

What you'll see: fifteen vertical spikes rising and falling like a sine wave, each capped with a small circle. A flat baseline runs across the middle, and spikes below it point downward where the signal goes negative.

A step plot draws a staircase instead of diagonal lines — the value holds flat, then jumps. This is perfect for quantities that stay constant until they change, like a price or a thermostat setting. Use ax.step(x, y, where=...) : where="pre" jumps before the point, "post" jumps after, and "mid" jumps halfway between.

What you'll see: a green staircase that stays flat between hours and then jumps straight up or down at each change, with a marker at every point. A faint gray dashed line connects the same points diagonally so you can feel the difference between "holds then jumps" and "slides smoothly."

ax.stairs() draws the outline of bars from bin edges and heights — exactly the shape a histogram makes, but as a clean line you can overlay or fill. The key rule: you pass one more edge than heights , because N bars need N+1 boundaries. Pair it with np.histogram() to outline a real distribution.

What you'll see: a bell-shaped staircase — tall in the middle, short at the edges — drawn both as a soft purple fill and as a crisp outline on top. It looks just like a histogram, but it's built from the counts and bin edges with no individual bar objects.

Replace each ___ to draw a stem plot and then a step plot of the same counts.

stairs needs exactly one more edge than heights. With 10 counts you must pass 11 edges.

Switch the where argument. Try "pre" , "post" , or "mid" to control when the step happens.

Stem plots are for a modest number of discrete samples. With hundreds of points, a line or histogram reads better.

Show one dataset three ways — a stem plot, a step plot, and a stairs outline — in a single row so you can compare them.

Lesson complete — you can plot discrete data clearly!

You drew spikes with ax.stem(), built staircases with ax.step() and drawstyle, outlined binned data with ax.stairs(), and learned when discrete plots beat a continuous line.

🚀 Up next: Polar Plots — plot data around a circle instead of a grid.

Practice quiz

What does a stem plot draw at each point?

  • A vertical line capped with a marker
  • A filled bar
  • A smooth curve
  • A pie slice

Answer: A vertical line capped with a marker. ax.stem draws a vertical stem from a baseline up to a marker at each value.

Which call makes a stem plot?

  • ax.spike(x, y)
  • ax.stem(x, y)
  • ax.bar(x, y)
  • ax.line(x, y)

Answer: ax.stem(x, y). ax.stem(x, y) draws a spike and marker at each (x, y).

How does ax.step() differ from ax.plot()?

  • It fills the area
  • It plots in 3D
  • It draws a staircase instead of diagonal lines
  • It uses polar axes

Answer: It draws a staircase instead of diagonal lines. ax.step() holds the value flat and then jumps, forming a staircase.

Which where= value makes the step jump after the point?

  • 'pre'
  • 'mid'
  • 'before'
  • 'post'

Answer: 'post'. where='post' holds the value then jumps after each point.

Which drawstyle on ax.plot() matches ax.step(where='post')?

  • drawstyle='steps-post'
  • drawstyle='post'
  • drawstyle='after'
  • drawstyle='jump'

Answer: drawstyle='steps-post'. ax.plot(x, y, drawstyle='steps-post') produces the same staircase.

What does ax.stairs() draw?

  • A scatter of points
  • The outline of bars from bin edges and heights
  • A smooth spline
  • A polar curve

Answer: The outline of bars from bin edges and heights. ax.stairs(counts, edges) outlines histogram-shaped bars from edges and heights.

How many edges does ax.stairs() need for N heights?

  • N - 1 edges
  • N edges
  • N + 1 edges
  • 2N edges

Answer: N + 1 edges. N bars need N+1 boundaries, so you pass one more edge than heights.

Which where= value jumps halfway between points?

  • 'mid'
  • 'half'
  • 'center'
  • 'between'

Answer: 'mid'. where='mid' makes the step jump halfway between each pair of points.

Which argument fills the area under ax.stairs()?

  • solid=True
  • shade=True
  • area=True
  • fill=True

Answer: fill=True. Pass fill=True to draw solid filled stairs.

When is a stem or step plot a poor choice?

  • For a few discrete samples
  • For hundreds of points where a line reads better
  • For sampled signals
  • For stepwise prices

Answer: For hundreds of points where a line reads better. With hundreds of points a stem plot looks crowded; a line or histogram is clearer.