Visualizing Data in R with ggplot2:
Scatter Plot

Asst. Prof. Dr. Somsak Chanaim

International College of Digital Innovation, CMU

June 24, 2026

What is a Scatter Plot?

A scatter plot is a type of data visualization that displays individual data points on a two-dimensional graph.

Each point on the scatter plot represents the values of two variables.

The position of a point on the x-axis corresponds to the value of one variable, while the position on the y-axis corresponds to the value of the other variable.

Key Features of a Scatter Plot:

  • Two Variables: Scatter plots typically show the relationship between two continuous variables.

  • Data Points: Each point represents an observation in the dataset.

  • Trends: Scatter plots are useful for identifying patterns, correlations, or trends between the two variables.

  • No Line: Unlike line plots, scatter plots do not connect the points with a line; each point stands alone.

When to Use a Scatter Plot

  • Correlation: To determine if there is a relationship between two variables.

  • Outliers: To spot any outliers or unusual observations in the data.

  • Trends: To visually inspect trends, such as whether one variable tends to increase as the other increases (positive correlation), decrease as the other increases (negative correlation), or show no clear pattern (no correlation).

Scatter plots are a fundamental tool in exploratory data analysis and are commonly used in various fields, including statistics, economics, and the natural sciences.

The geom_point() function in ggplot2

The geom_point() function in ggplot2 is used to create scatter plots.

Exercise Basic Usage

data |> 
ggplot() +
  aes(x = variable1, y = variable2) +
  geom_point()
  • data: The dataset being used.

  • aes(x = variable1, y = variable2): Defines the aesthetics, mapping the variables to the x and y axes. (x and y are continuous or integer number)

  • geom_point(): Adds the points to the plot.

Example

Let’s create a basic scatter plot using the mpg dataset:

This code creates a scatter plot of engine displacement (displ) versus highway miles per gallon (hwy).

Customizing geom_point()

Changing Point Color

You can change the color of the points using the color argument:

Mapping Color to a Variable

You can map a color to a variable, which will change the color of the points based on the values of that variable:

In this case, points will be colored based on the car’s class.

Modify color

The scale_color_manual() function

Changing Point Size

You can adjust the size of the points with the size argument:

The default of size is one.

Mapping Size to a Variable

You can map the size of the points to a variable:

Here, the size of each point corresponds to the number of cylinders (cyl).

Changing Point Shape

The shape of the points can be changed using the shape argument:

Combining Aesthetics

You can combine multiple aesthetics (color, size, shape) in one plot:

This creates a scatter plot where the color represents the car class, the shape represents the drv (drive type), and the size of the points is fixed.

Modify shape

The scale_shape_manual() function

Customized axis ranges.

xlim() and ylim()

xlim() and ylim() are functions that control the limits of the x and y axes, respectively.

These functions are often used together to create scatter plots with customized axis ranges.

  • xlim(<x_min>, <x_max>): Sets the minimum and maximum limits for the x-axis.

  • ylim(<y_min>, <y_max>): Sets the minimum and maximum limits for the y-axis.

Suppose you want to create a scatter plot using the mpg dataset to show the relationship between engine displacement (displ) and highway miles per gallon (hwy), and you want to restrict the x-axis to the range 2 to 6 and the y-axis to the range 15 to 40.

Explanation:

  • xlim(2, 6): Sets the x-axis to display values between 2 and 6.

  • ylim(15, 40): Sets the y-axis to display values between 15 and 40.

Adding a Regression Line

To add a regression line to a scatter plot in ggplot2 after using geom_point(), you can use the geom_smooth() function.

The geom_smooth() function can fit and add a variety of trend lines to your plot, including linear regression lines.

Using the mpg dataset to create a scatter plot of engine displacement (displ) versus highway miles per gallon (hwy), with a linear regression line added:

Explanation:

  • geom_point(): Creates a scatter plot of displ versus hwy.

  • geom_smooth(method = "lm", se = FALSE):

    • method = "lm": Specifies that a linear model (linear regression) should be fitted to the data.

    • se = FALSE: Removes the confidence interval shading around the regression line. If you want to display the confidence interval, you can set se = TRUE or omit the argument.

Adding Confidence Interval:

By default, geom_smooth() adds a shaded area around the regression line representing the confidence interval. You can enable or disable this with the se argument:

Changing Line Color:

We can change the color of the regression line using the color argument:

Changing Line Type:

To change the type of line (e.g., dashed, dotted), use the linetype argument:

Adding Non-Linear Trend Lines:

If we want to fit a non-linear model (e.g., a LOESS curve), you can specify a different method in geom_smooth():

After this you can modifies color, linetype, or se to non-linear line.

Exercise

Use the Gapminder dataset from the gapminder package.

Exercise 1: Fundamental Bivariate Scatter Plots

Complete the data pipeline to filter rows by a specific baseline year and construct a continuous bivariate scatter plot using numeric axes.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp) +
()

Exercise 2: Discrete Group Aesthetic Mapping

Complete the plotting configuration to map the discrete continent variable onto the point color parameter, enabling visual group segmentation across the coordinates.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp, = continent) +
geom_point()

Exercise 3: Continuous Numeric Scale Mapping

Complete the plotting block to map a third dimension onto the visualization, scaling the physical point sizes dynamically by population counts.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp, color = continent, = pop) +
geom_point()

Exercise 4: Logarithmic Axis Scaling and Transformation

Complete the plotting pipeline to apply a base-10 logarithmic transformation to the horizontal numeric scale, stabilizing variance across exponential GDP values.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp, color = continent, size = pop) +
() +
geom_point()

Exercise 5: Linear Regression Superimposition

Complete the data visualization pipeline to fit and overlay a linear smoothing metric across the bivariate scatter coordinates.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp) +
geom_point() +
(method = "lm", se = FALSE)

Exercise 6: Conditional Grid Panel Matrix

Complete the plotting configuration to decouple a unified scatter coordinate field into a discrete series of comparative panels separated by categorical continent properties.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp) +
geom_point() +
(. ~ )

Exercise 7: Multi-Dimensional Cross-Tabulated Facet Grids

Complete the plotting block to construct a comprehensive 2D facet grid matrix, cross-tabulating the continuous bivariate distribution simultaneously by rows (continent) and columns (year).

Target output

Complete the code

library(ggplot2)
library(gapminder)
gapminder |>
ggplot() +
aes(x = gdpPercap, y = lifeExp) +
geom_point() +
( ~ )

Exercise 8: Target Observation Highlighting and Identity Scales

Complete the data structure assignment and plotting pipeline to inject a dynamic structural vector tracking target nations and instruct ggplot2 to interpret literal string color characters directly.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder$COLOR = (gapminder$country %in% c("China", "India", "United States"), "red", "black")
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp, color = COLOR) +
geom_point() +
()

Exercise 9: Discrete Shape Aesthetic Mapping

Complete the plotting configuration to map the discrete continent classification variable onto individual geometric point markers.

Target output

Complete the code

library(dplyr)
library(ggplot2)
library(gapminder)
gapminder |>
filter(year == 2007) |>
ggplot() +
aes(x = gdpPercap, y = lifeExp, = continent) +
geom_point() +
scale_color_identity()

Color in ggplot2

Input