Plotting Multiple Lines
Most real line charts show several series - time, competitors, before/after - and matplotlib handles this with one call per series on the same Axes. It cycles through a default color palette automatically, and a legend (next chapter) disambiguates the lines. This chapter covers the multi-series pattern, controlling the cycle, and the classic missing-data case where a line must break.
Several Series, One Axes
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi, 200)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), label="sin(x)")
ax.plot(x, np.cos(x), label="cos(x)")
ax.plot(x, np.sin(2 * x), linestyle="--", label="sin(2x)")
ax.set_xlabel("x (radians)")
ax.set_ylabel("value")
plt.show()
Each ax.plot adds one Line2D to the same Axes; the first three calls get the palette's first three colors automatically, and the explicit linestyle distinguishes the third line beyond color alone - important for color-blind readers and grayscale printing.
Controlling the Color Cycle
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
for i in range(4):
ax.plot([0, 1, 2], [i, i + 1, i],
color=plt.rcParams["axes.prop_cycle"].by_key()["color"][i],
label=f"series {i}")
ax.legend()
plt.show()
The active palette lives in rcParams["axes.prop_cycle"]; index into it for programmatic multi-series charts, or set the whole cycle with a named palette (plt.style.use, covered in the styling chapter). With more series than palette colors, the cycle repeats - beyond ~8 lines, vary linestyle and marker, not just color.
Missing Data and Broken Lines
Matplotlib connects points in order, so a gap must be an explicit NaN - the line breaks at any non-finite value:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(10)
y = np.array([1, 2, 3, np.nan, np.nan, 6, 7, np.nan, 9, 10], dtype=float)
fig, ax = plt.subplots()
ax.plot(x, y, marker="o") # gaps where y is NaN
ax.plot(x, y, linestyle=":", alpha=0.4) # dotted "what we might have known"
plt.show()
The solid line with markers shows the measured segments; the dotted overlay is a common convention for indicating where data is missing. If your source data is None or a sentinel value, convert it to NaN before plotting - np.where(value == -999, np.nan, value).
Mixing Line Types for Emphasis
- Reference lines (targets, baselines) as dashed or dotted, in gray, with
zorderbelow the data lines. - The "hero" series solid and thick (
linewidth=2.5); supporting series thin (linewidth=1.0) and desaturated. - Annotations for single important points (the annotations chapter) rather than crowding every series with markers.
Summary
Draw multiple lines with one ax.plot per series on a shared Axes: the color cycle and a legend do the disambiguation, and you control it per line with color, linestyle, linewidth, and zorder. Encode missing values as NaN to break the line, and emphasize one series by making the others quieter, not by making the hero louder.