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

Lesson 03

Scatter Plots with hue, size, and style

Draw relationships with sns.scatterplot and map more columns onto colour, marker size, and marker shape with hue, size, and style, legend included.

Intermediate25 min
Scatter Plots with hue, size, and style hero Module 26 Lesson 3Scatter Plots with hue, size, and style hero Module 26 Lesson 3

A scatter plot answers one question: when one measurement goes up, what does the other do? Seaborn's scatterplot adds three more channels on top of x and y. hue sets colour, size sets how big each dot is, and style sets its shape, and each can come from a column.

Scatter plot of hours against score with dots coloured by trackScatter plot of hours against score with dots coloured by track

Hours against score

The dots climb from left to right: learners who studied more tended to score higher. The printed correlation puts a number on that, where 1 is a perfect upward line and 0 is no pattern.

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.scatterplot(data=study, x="hours", y="score")
plt.show()

print(round(study["hours"].corr(study["score"]), 2))

Output:

text
0.82

Colour by a category with hue

hue="track" gives each track its own colour and a legend. palette picks the colours, either a named palette or a dictionary from each value to a colour. hue_order fixes the legend order.

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()

colours = {"Python": "#7C3AED", "Data": "#2563EB", "Web": "#EC4899"}
sns.scatterplot(data=study, x="hours", y="score", hue="track",
                palette=colours, hue_order=["Python", "Data", "Web"])
plt.show()

print(study["track"].value_counts())

Output:

text
track
Web       51
Python    35
Data      34
Name: count, dtype: int64

A numeric hue becomes a colour scale

When the hue column holds numbers, Seaborn uses a smooth colour scale instead of separate colours. Here darker dots are later weeks, and the later weeks sit further right.

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.scatterplot(data=study, x="hours", y="score", hue="week", palette="flare")
plt.show()

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

Output:

text
week
1    4.1
2    5.0
3    6.1
4    6.1
5    7.6
6    8.6
Name: hours, dtype: float64

size and style

size scales each dot by a column and sizes=(small, big) sets the range in points squared. style gives each category its own marker shape, which still works when the chart is printed in grey.

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.scatterplot(data=study, x="hours", y="score",
                size="week", sizes=(15, 160), style="mode", alpha=0.7)
plt.legend(bbox_to_anchor=(1.02, 1), loc="upper left")
plt.show()

print(sorted(study["mode"].unique()))

Output:

text
['classroom', 'online']

Every mapping adds a legend section. Two extra channels is usually the limit before the chart becomes hard to read.

Key takeaways

  • scatterplot shows how two numeric columns move together

  • hue sets colour: separate colours for categories, a scale for numbers

  • size scales dots by a column; sizes= sets the range

  • style changes marker shape, which survives greyscale printing

  • Next: Line Plots and Error Bands

  • Previous: Tidy Data for Seaborn

Loading playground…

Check your understanding

Scatter Plots with hue, size, and style Quiz

What question does a scatter plot answer?

1 / 10