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.
