How to Plot Multiple Lines in Python (Matplotlib, NumPy, pandas)

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()
Matplotlib window with three lines on the same graph, the monthly temperatures of New York, Chicago and Miami, with a legend
Three 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
Command Prompt screenshot listing the label, color and number of points of each line on a Matplotlib axes with get_lines
Inspecting the lines of a plot in the Windows Command Prompt.

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)
Matplotlib window with sin(x), cos(x) and sin(2x) plotted from the columns of one NumPy array in a single plot call
One 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()
Matplotlib window with three lines using different colors, solid, dashed and dotted line styles and circle and square markers
Set 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()
Matplotlib window with six sine curves drawn in a loop, coloured from the viridis colormap, with a two-column legend
Six lines coloured along the viridis colormap.

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()
pandas DataFrame plot with three lines for laptop, phone and tablet sales per month and markers on each point
One line for each DataFrame column.

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()
Matplotlib window with four city temperature lines, labels written at the end of each line and the legend placed outside the plot
Labels at the line ends, and the legend moved outside the axes.

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()
Three stacked Matplotlib subplots sharing the x-axis with revenue, costs and profit lines
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()
Matplotlib window with revenue on the left y-axis and margin percentage on a second right y-axis created with twinx
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:

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.