Skip to main content
MahiDev — Learn. Build. Become AI-ready.

Lesson 04

Line Plots and Error Bands

Use sns.lineplot to draw trends, let Seaborn average repeated x values for you, and read or change the shaded band with errorbar, estimator, and hue.

Intermediate25 min
Line Plots and Error Bands hero Module 26 Lesson 4Line Plots and Error Bands hero Module 26 Lesson 4

Our table has about twenty rows for every week. A plain Matplotlib line would zigzag through all of them. sns.lineplot groups the rows that share an x value, draws their mean as the line, and shades a band that shows how sure that mean is.

Two mean lines of weekly study hours with shaded confidence bandsTwo mean lines of weekly study hours with shaded confidence bands

Repeated x values are averaged

Each week has many rows. lineplot draws one point per week at the mean, exactly the numbers groupby prints below, and joins them.

python
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

rng = np.random.default_rng(26)
study = pd.DataFrame({
    "track": rng.choice(["Python", "Data", "Web"], 120),
    "mode": rng.choice(["online", "classroom"], 120),
    "week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()

sns.lineplot(data=study, x="week", y="hours")
plt.show()

print(study.groupby("week")["hours"].mean().round(2))

Output:

text
week
1    4.15
2    5.01
3    6.11
4    6.14
5    7.61
6    8.58
Name: hours, dtype: float64

What the band means

The default band is a 95% confidence interval, found by resampling the rows many times. A narrow band means the mean is well pinned down. errorbar="sd" shows one standard deviation instead, which describes the spread of the rows rather than the certainty of the mean. errorbar=None removes it.

python
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

rng = np.random.default_rng(26)
study = pd.DataFrame({
    "track": rng.choice(["Python", "Data", "Web"], 120),
    "mode": rng.choice(["online", "classroom"], 120),
    "week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()

fig, axes = plt.subplots(1, 3, figsize=(12, 3.5), sharey=True)
for ax, choice in zip(axes, [("ci", 95), "sd", None]):
    sns.lineplot(data=study, x="week", y="hours", errorbar=choice, ax=ax)
    ax.set_title(f"errorbar={choice!r}")
plt.show()

print(study.groupby("week")["hours"].std().round(2))

Output:

text
week
1    1.59
2    1.36
3    1.60
4    1.45
5    1.52
6    1.23
Name: hours, dtype: float64

One line per group

hue splits the rows into one line per group. Adding style with the same column gives each line its own dash pattern, and markers=True marks every mean.

python
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

rng = np.random.default_rng(26)
study = pd.DataFrame({
    "track": rng.choice(["Python", "Data", "Web"], 120),
    "mode": rng.choice(["online", "classroom"], 120),
    "week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()

sns.lineplot(data=study, x="week", y="hours", hue="mode", style="mode", markers=True)
plt.show()

print(study.pivot_table(index="week", columns="mode", values="hours").round(2))

Output:

text
mode  classroom  online
week                   
1          4.00    4.22
2          5.44    4.67
3          6.00    6.25
4          6.72    5.87
5          7.71    7.50
6          9.01    8.17

Choose the estimator

estimator picks how the rows for each x are combined. "median" is steadier when a few rows are extreme, and "sum" totals them. Pass None to draw every row as it is, which only makes sense when each x appears once.

python
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

rng = np.random.default_rng(26)
study = pd.DataFrame({
    "track": rng.choice(["Python", "Data", "Web"], 120),
    "mode": rng.choice(["online", "classroom"], 120),
    "week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()

sns.lineplot(data=study, x="week", y="score", estimator="median", errorbar=None, marker="o")
plt.show()

print(study.groupby("week")["score"].median())

Output:

text
week
1    53.0
2    58.5
3    64.5
4    65.0
5    66.0
6    74.0
Name: score, dtype: float64

Key takeaways

  • lineplot averages rows that share an x value and joins the means

  • The default band is a bootstrapped 95% confidence interval

  • errorbar="sd" shows spread; errorbar=None removes the band

  • hue splits lines by group; estimator changes mean to median or sum

  • Next: relplot and Small Multiples

  • Previous: Scatter Plots with hue, size, and style

Loading playground…

Check your understanding

Line Plots and Error Bands Quiz

What does lineplot do with several rows at the same x?

1 / 10