R ggplot2 Scatter Plot

A scatter plot shows the relationship between two numeric variables. Each point represents one observation. Scatter plots reveal correlations, clusters, outliers, and patterns that are invisible in summary statistics alone. ggplot2's geom_point() builds them.

Basic Scatter Plot

library(ggplot2)

students <- data.frame(
  study_hours = c(1,2,3,4,5,6,7,8,9,10,3,5,7,2,8),
  score       = c(45,52,60,65,72,78,82,88,90,95,58,70,85,50,92),
  gender      = rep(c("M","F","M"), 5)
)

ggplot(students, aes(x=study_hours, y=score)) +
  geom_point(size=3, color="steelblue", alpha=0.7) +
  labs(title="Study Hours vs Exam Score",
       x="Daily Study Hours", y="Exam Score") +
  theme_minimal()

Color by Group

ggplot(students, aes(x=study_hours, y=score, color=gender)) +
  geom_point(size=3, alpha=0.8) +
  scale_color_manual(values=c("M"="steelblue","F"="tomato")) +
  labs(title="Study Hours vs Score by Gender",
       color="Gender") +
  theme_minimal()

Size by a Third Variable (Bubble Chart)

countries <- data.frame(
  gdp_per_cap = c(2000,5000,12000,25000,40000,55000),
  life_exp    = c(55,63,70,76,80,83),
  population  = c(100,50,200,80,30,10),   # millions
  continent   = c("Asia","Asia","Asia","Europe","Europe","Europe")
)

ggplot(countries, aes(x=gdp_per_cap, y=life_exp,
                       size=population, color=continent)) +
  geom_point(alpha=0.7) +
  scale_size_continuous(range=c(3,15)) +
  labs(title="GDP vs Life Expectancy (Bubble = Population)",
       x="GDP per Capita (USD)", y="Life Expectancy (years)",
       size="Population (M)", color="Continent") +
  theme_minimal()
Bubble chart anatomy:
  Life
  Exp │      ○  Large bubble = high population
      │   ●       ◎
      │ ●             ○
      └──────────────── GDP per Capita
  Color = continent

Adding a Regression Line

ggplot(students, aes(x=study_hours, y=score)) +
  geom_point(color="steelblue", alpha=0.7, size=3) +
  geom_smooth(method="lm", color="red", fill="pink", alpha=0.2) +
  labs(title="Score vs Study Hours with Trend Line") +
  theme_minimal()

Adding Labels to Points

top_students <- students[students$score >= 88, ]

ggplot(students, aes(x=study_hours, y=score)) +
  geom_point(color="steelblue", alpha=0.6, size=3) +
  geom_text(data=top_students,
            aes(label=paste0(score)),
            vjust=-1, size=3, color="red") +
  labs(title="Score vs Study Hours (top scorers labeled)") +
  theme_minimal()

Overplotting — When Too Many Points Overlap

# For many overlapping points, use jitter or transparency
ggplot(students, aes(x=factor(round(study_hours)), y=score)) +
  geom_jitter(width=0.2, alpha=0.5, color="steelblue") +
  labs(x="Study Hours", y="Score") +
  theme_minimal()

# Or use geom_count to show point count by size
ggplot(students, aes(x=round(study_hours), y=round(score,-1))) +
  geom_count(color="steelblue") +
  theme_minimal()

Faceted Scatter Plots

ggplot(students, aes(x=study_hours, y=score)) +
  geom_point(aes(color=gender), size=2.5) +
  geom_smooth(method="lm", se=FALSE, color="gray40") +
  facet_wrap(~gender) +
  theme_minimal()

Highlighting Quadrants

ggplot(students, aes(x=study_hours, y=score)) +
  annotate("rect", xmin=5, xmax=Inf, ymin=75, ymax=Inf,
           alpha=0.1, fill="green") +      # high hours, high score
  annotate("rect", xmin=-Inf, xmax=5, ymin=-Inf, ymax=75,
           alpha=0.1, fill="red") +        # low hours, low score
  geom_point(size=3, color="steelblue") +
  geom_hline(yintercept=75, linetype="dashed", color="gray") +
  geom_vline(xintercept=5, linetype="dashed", color="gray") +
  theme_minimal()

Scatter plots are the most powerful tool for exploring relationships between variables. Correlation coefficients and regression outputs summarize the relationship numerically, but scatter plots show you the actual shape — whether it is linear, curved, clustered, or driven by outliers. Always plot the raw data before fitting any model.

Leave a Comment

Your email address will not be published. Required fields are marked *