To plot multiple lines in Python, call plt.plot() once for each line before plt.show(): every call adds another line to the same graph. Give each line a label and call plt.legend() so readers can tell them apart. You can also plot all columns of a NumPy array or a pandas DataFrame in one call. This guide covers each approach with real Matplotlib windows, plus colors and styles, many lines in a loop, legends, subplots and lines on different scales.
Every example was run with Python 3.12.5, Matplotlib 3.11.2, NumPy 2.5.3 and pandas 3.0.6; the screenshots are the real Matplotlib windows. The full list of line options is in the Matplotlib reference for pyplot.plot.
Plot multiple lines on the same graph
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
new_york = [3, 5, 10, 16, 21, 26]
chicago = [-3, -1, 5, 11, 17, 22]
miami = [20, 21, 23, 25, 27, 28]
plt.plot(months, new_york, label="New York") # each plot() call adds one line
plt.plot(months, chicago, label="Chicago")
plt.plot(months, miami, label="Miami")
plt.title("Average temperature (°C)")
plt.legend()
plt.show()
plt.plot() calls, one graph, one legend.Matplotlib gives each new line the next colour in its cycle automatically. You can check what is on the axes with ax.get_lines():
import matplotlib.pyplot as plt
from matplotlib.colors import to_hex
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
fig, ax = plt.subplots()
ax.plot(months, [3, 5, 10, 16, 21, 26], label="New York")
ax.plot(months, [-3, -1, 5, 11, 17, 22], label="Chicago")
for line in ax.get_lines():
print(f"{line.get_label():10} color={to_hex(line.get_color())} points={len(line.get_xdata())}")
Output:
New York color=#1f77b4 points=6
Chicago color=#ff7f0e points=6
Plot multiple lines from a NumPy array
If y is a 2-D array, plot() draws one line per column. Since Matplotlib 3.4 you can pass a list of labels too:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
Y = np.column_stack([np.sin(x), np.cos(x), np.sin(2 * x)]) # shape (100, 3): one column per line
lines = plt.plot(x, Y, label=["sin(x)", "cos(x)", "sin(2x)"]) # one call, three lines
print(len(lines), "lines from an array of shape", Y.shape)
plt.legend()
plt.show()
Output:
3 lines from an array of shape (100, 3)
plt.plot(x, Y) call draws a line for each column of Y.Different colors, line styles and markers
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
plt.plot(months, [3, 5, 10, 16, 21, 26], color="tab:red", linestyle="-", marker="o", label="New York")
plt.plot(months, [-3, -1, 5, 11, 17, 22], color="tab:blue", linestyle="--", marker="s", label="Chicago")
plt.plot(months, [20, 21, 23, 25, 27, 28], color="tab:green", linestyle=":", linewidth=3, label="Miami")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
color, linestyle, marker and linewidth per line.Many lines in a loop
For more than a handful of lines, loop over the data and take the colours from a colormap so neighbouring lines are easy to tell apart:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 200)
frequencies = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
colors = plt.cm.viridis(np.linspace(0, 1, len(frequencies))) # one colour per line
fig, ax = plt.subplots(figsize=(8, 4.5))
for f, color in zip(frequencies, colors):
ax.plot(x, np.sin(f * x) + f, color=color, label=f"f = {f}")
ax.legend(ncols=2, fontsize=9)
plt.tight_layout()
plt.show()
Plot multiple lines from a pandas DataFrame
DataFrame.plot() draws one line per column. Choose the x column with x= and the lines with y=[...]:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
"month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
"Laptops": [120, 135, 150, 160, 172, 190],
"Phones": [200, 190, 210, 230, 225, 240],
"Tablets": [80, 85, 83, 90, 95, 100],
})
ax = df.plot(x="month", y=["Laptops", "Phones", "Tablets"], marker="o", figsize=(7, 4)) # one line per column
ax.set_ylabel("Units sold")
plt.tight_layout()
plt.show()
Legend placement and labels at the end of lines
With several lines, a legend inside the plot can hide data. Move it outside with bbox_to_anchor, or write each label next to the last point of its line:
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
fig, ax = plt.subplots(figsize=(8, 4))
for city, temps in {"New York": [3, 5, 10, 16, 21, 26], "Chicago": [-3, -1, 5, 11, 17, 22],
"Miami": [20, 21, 23, 25, 27, 28], "Seattle": [6, 7, 9, 12, 15, 18]}.items():
line, = ax.plot(months, temps)
ax.annotate(city, (months[-1], temps[-1]), xytext=(6, 0), textcoords="offset points",
color=line.get_color(), va="center") # label at the end of each line
ax.legend(ax.get_lines(), ["New York", "Chicago", "Miami", "Seattle"],
loc="upper left", bbox_to_anchor=(1.12, 1)) # legend outside the axes
plt.tight_layout()
plt.show()
More legend options: put the legend outside the plot and change the legend font size.
One line per subplot
When lines have different units or would overlap too much, give each one its own subplot and share the x-axis:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(1, 13)
series = {"Revenue": x * 10 + 5, "Costs": x * 7 + 20, "Profit": x * 3 - 15}
fig, axes = plt.subplots(3, 1, figsize=(7, 6), sharex=True)
for ax, (name, y) in zip(axes, series.items()):
ax.plot(x, y, marker="o")
ax.set_title(name, fontsize=10)
axes[-1].set_xlabel("Month")
plt.tight_layout()
plt.show()
plt.subplots(3, 1, sharex=True): one line per panel.Two lines with different y scales
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
fig, ax1 = plt.subplots(figsize=(7, 4))
ax1.plot(months, [120, 135, 150, 160, 172, 190], color="tab:blue", label="Revenue (k$)")
ax2 = ax1.twinx() # second y-axis for a line on a different scale
ax2.plot(months, [8.5, 9.1, 9.8, 10.2, 10.1, 11.0], color="tab:red", label="Margin (%)")
fig.legend(loc="upper left", bbox_to_anchor=(0.12, 0.88))
plt.tight_layout()
plt.show()
twinx() adds a second y-axis for a line on a different scale.Set each axis range separately as shown in set the y-axis range in Matplotlib.
More Matplotlib line and figure tutorials:
- Plot multiple horizontal lines in Matplotlib
- Create multiple plots in one figure
- Put the legend outside the plot
- Set the axis range in Matplotlib
Frequently asked questions
How do I plot multiple lines on the same graph in Matplotlib?
Call plt.plot(x, y, label="...") once for each line, then plt.legend() and plt.show(). All lines drawn before show() share the same axes.
How do I plot two lines on the same graph in Python?
Two plot() calls: plt.plot(x, y1) and plt.plot(x, y2). Add label= and plt.legend() to name them.
How do I plot multiple lines from a pandas DataFrame?
df.plot(x="column_for_x", y=["col1", "col2"]) draws one line per listed column.
How do I give each line a different color?
Pass color= to each plot() call, or loop over colours from a colormap such as plt.cm.viridis.
How do I plot multiple lines from a NumPy array?
Put the lines in the columns of a 2-D array and call plt.plot(x, Y); each column becomes a line.
How do I plot lines with very different values?
Use a second y-axis with ax.twinx(), or put each line in its own subplot.
Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn