To plot multiple lines on one set of axes, call Matplotlib’s ax.plot() once for each series, or pass a shared x vector and a two-dimensional y array. If your data is in a pandas DataFrame, select the columns with df.plot(). Give each line a label and add a legend so readers can tell them apart.
Start with separate x/y pairs
Use a separate ax.plot() call for each series. This approach is easy to read and works when lines have different x coordinates or need different styles.
import matplotlib.pyplot as plt
x_a = [1, 2, 3, 4]
y_a = [2, 4, 3, 5]
x_b = [1, 2, 3, 4]
y_b = [1, 3, 4, 4]
fig, ax = plt.subplots()
ax.plot(x_a, y_a, label="Series A")
ax.plot(x_b, y_b, label="Series B")
ax.set_xlabel("X")
ax.set_ylabel("Value")
ax.set_title("Series comparison")
ax.legend()
plt.show()
plt.subplots() returns a Figure and an Axes; add the lines and configure the chart through the Axes. Matplotlib also supports the shorter plt.plot() interface, which uses implicit state. The explicit Axes approach is a useful foundation as a plot becomes more involved. See the Matplotlib quick start guide and pyplot reference.
Choose an input pattern that matches your data
| Data shape or need | Starting point | Why it fits |
|---|---|---|
| Separate series, possibly with different x values | Repeated ax.plot(x_i, y_i) calls |
Each line has its own x data and can be styled or labeled separately. |
| One shared x vector and a column-oriented matrix | ax.plot(x, Y) |
Matplotlib treats each column of the two-dimensional Y array as a dataset. |
| Named columns in a pandas DataFrame | df.plot(x=..., y=[...]) |
Column names make it convenient to select the desired series. |
| Lines that should not share one scale or are difficult to compare together | Separate Axes or subplots | Separate panels can make values easier to read; pandas supports subplot plotting. |
The Matplotlib plot reference documents repeated x/y groups and two-dimensional inputs. The pandas DataFrame.plot reference and visualization guide describe the DataFrame options.
#1 Best Overall
Plot a shared x vector with a NumPy array
When each series uses the same x coordinates, arrange values in a two-dimensional array with one series per column. Matplotlib draws one line for each column:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([1, 2, 3, 4])
Y = np.array([
[2, 1],
[4, 3],
[3, 4],
[5, 4],
])
fig, ax = plt.subplots()
ax.plot(x, Y)
ax.set_xlabel("X")
ax.set_ylabel("Value")
ax.legend(["Series A", "Series B"])
plt.show()
Here, the rows correspond to x positions and the two columns hold the two series. This is equivalent to plotting each column separately, such as Y[:, 0] and Y[:, 1]. Check Y.shape before plotting: if your data stores one series per row, transpose it so the series are columns. If both x and y are two-dimensional, Matplotlib requires matching shapes.
Rank #2
Plot selected pandas DataFrame columns
DataFrame.plot() makes a line plot by default, using the DataFrame index for x values. Specify x and y to control which columns are plotted:
ax = df.plot(
x="date",
y=["observed", "model_a", "model_b"],
title="Observed and modeled values",
)
ax.set_ylabel("Measurement")
ax.legend(title="Series")
If the index should be the x axis, omit x and select the lines with y, for example df.plot(y=["temperature", "pressure"]). If you already have an Axes, pass it with ax=ax to draw the DataFrame lines there. Selecting y explicitly helps avoid plotting numeric columns—such as IDs or unrelated measures—that are present in the table but do not belong in the comparison.
Make every line distinguishable
Give each line a meaningful label and call ax.legend(). Use the default color cycle for a quick chart, or distinguish series with a combination of color, markers, and line styles. When there are many lines, keep the comparison focused and do not rely on color alone.
Label each axis with the quantity and, where relevant, its unit. Use a specific title that tells readers what is being compared. Matplotlib’s plot() supports line properties such as color, marker, linestyle, and linewidth. Styling passed to a single call containing multiple datasets applies to those datasets together; make separate calls when individual lines need distinct styling.
Check common plotting problems
- Different point counts: each x/y pair needs corresponding observations. Check that their lengths match and that the values are aligned.
- Unexpected number of lines: a two-dimensional y input creates one line per column. Inspect its shape and orientation, and transpose row-oriented data if needed.
- Too many pandas lines: DataFrame plotting can include numeric columns you did not mean to compare. Set
yto the intended column names. - Unclear legend: add useful labels to the lines and call
ax.legend(); otherwise the series may be hard to identify. - Hard-to-read shared scale: if series have incompatible scales or overlap too much, use separate subplots rather than forcing the comparison onto one axis.
Check documentation for your installed versions
The stable documentation consulted for this guide is labeled Matplotlib 3.11.2 for plot, the quick start, and the documentation overview; the pyplot reference is labeled 3.11.1. The pandas DataFrame plotting reference is labeled 3.0.5, and its visualization guide 3.0.4. Those labels identify the documentation versions, not the versions installed in your environment. For version-specific behavior, consult the documentation matching your installed Matplotlib or pandas release: Matplotlib documentation.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.




