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().
What You'll Learn in This Lesson
1 Stem Plots for Discrete Signals
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.
2 Step Plots & drawstyle
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."
3 Histogram Outlines With ax.stairs()
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.
🎯 Your Turn: Fill in the Blanks
Replace each ___ to draw a stem plot and then a step plot of the same counts.
📋 Common Errors & Quick Reference
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.
Call
What It Does
ax.stem(x, y)
Spike + marker per point
ax.step(x, y, where="post")
Staircase, jump after point
drawstyle="steps-pre"
Step via ax.plot()
ax.stairs(h, edges)
Outline from bins
fill=True
Solid filled stairs
🎯 Mini-Challenge: Three Discrete Views
Show one dataset three ways — a stem plot, a step plot, and a stairs outline — in a single row so you can compare them.
❓ Frequently Asked Questions
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.
Continue this course
- Previous: Filling Areas (fill_between)
- Next: Polar Plots