International College of Digital Innovation, CMU
June 24, 2026
The ggplot2 package is one of the most popular and powerful data visualization packages in R.
It is based on the “Grammar of Graphics”, a framework that breaks down graphs into components such as scales, layers, and themes.
This approach allows users to build complex and customized plots in a systematic and consistent way.
Benefits of Using ggplot2:
Consistency: The grammar of graphics approach makes it easier to build and understand plots.
Flexibility: It allows for extensive customization, from simple plots to complex multi-layered visualizations.
Community Support: As one of the most widely used R packages, ggplot2 has a large community, extensive documentation, and numerous tutorials and examples.
To create a visualization in ggplot2, the primary requirement is that your data must be structured as a Data Frame. Unlike base R plotting functions that might accept vectors or matrices, ggplot2 is designed around the Grammar of Graphics, which treats data as a structured object where columns represent variables and rows represent observations.
Format Requirement: The data argument in the ggplot() function must explicitly be a data.frame or a tibble.
Variable Mapping: Within a histogram, you map a specific column from your data frame to the x-axis using the aes() (aesthetics) function.
Tidy Data: For the best results, your data should be in a “tidy” format, meaning each variable has its own column.
Open your R console or RStudio and run the following command:
This command will download and install ggplot2.
Load the Package
After installation, you need to load the package into your R session using the library() function:
The basic structure typically involves the following components:
Data: The dataset (data frame) that you want to visualize.
Aesthetics (aes): Mappings of data variables to visual properties like x and y coordinates, colors, sizes, and shapes.
Geometries (geom): The type of plot or visual elements to represent the data (e.g., points, lines, bars).
Facets: Optional; used to create multiple plots based on subsets of the data.
Scales: Optional; used to control the mapping of data to aesthetics.
Coordinates: Optional; control the coordinate system.
Themes: Optional; used to customize the appearance of the plot.
Let’s break down an example of creating a scatter plot using ggplot2:
Basic Structure
After load the package ggplot2
Explanation:
geom_histogram() creates the histogram.
bins = 30 Specifies the number of bins instead of using
fill = "skyblue" sets the fill color of the bars.
color = "black" outlines the bars in black.
After create the ggplot object if we need to modifies/add titles, axis labels, legends, or captions etc.
We use the labs() function to customize the labels of various elements in a plot, including titles, axis labels, legends, and captions.
labs(
title = NULL, # Title of the plot
subtitle = NULL, # Subtitle of the plot
x = NULL, # Label for the x-axis
y = NULL, # Label for the y-axis
caption = NULL, # Caption at the bottom of the plot
tag = NULL, # Tag for the plot (like a figure number)
fill = NULL, # Label for fill legend (if applicable)
color = NULL, # Label for color legend (if applicable)
size = NULL, # Label for size legend (if applicable)
shape = NULL # Label for shape legend (if applicable)
)Question:
Add, the title is “The histogram of N(0,1)”
the caption is ‘Your Name’.
The default theme is theme_gray().
Complete the ggplot2 script to visualize the single-variable distribution of miles per gallon, adjusting the analytical bin width configuration.
viewof var_ch10_ex1_basic_histogram_1 = html`<input type="text" class="ojs-hidden-ch10_ex1_basic_histogram" data-ojs-proxy="ch10_ex1_basic_histogram::var_ch10_ex1_basic_histogram_1" value="">`
viewof var_ch10_ex1_basic_histogram_2 = html`<input type="text" class="ojs-hidden-ch10_ex1_basic_histogram" data-ojs-proxy="ch10_ex1_basic_histogram::var_ch10_ex1_basic_histogram_2" value="">`
viewof var_ch10_ex1_basic_histogram_run = html`<input type="number" class="ojs-hidden-ch10_ex1_basic_histogram" data-ojs-run="ch10_ex1_basic_histogram" value="0">`Modify the baseline histogram script by injecting parameters to alter the visual fill and structural boundary colors of the data bars.
viewof var_ch10_ex2_customized_histogram_colors_1 = html`<input type="text" class="ojs-hidden-ch10_ex2_customized_histogram_colors" data-ojs-proxy="ch10_ex2_customized_histogram_colors::var_ch10_ex2_customized_histogram_colors_1" value="">`
viewof var_ch10_ex2_customized_histogram_colors_2 = html`<input type="text" class="ojs-hidden-ch10_ex2_customized_histogram_colors" data-ojs-proxy="ch10_ex2_customized_histogram_colors::var_ch10_ex2_customized_histogram_colors_2" value="">`
viewof var_ch10_ex2_customized_histogram_colors_run = html`<input type="number" class="ojs-hidden-ch10_ex2_customized_histogram_colors" data-ojs-run="ch10_ex2_customized_histogram_colors" value="0">`Complete the script to scale the y-axis to statistical density and overlay a smoothed density line layer onto the histogram.
viewof var_ch10_ex3_histogram_density_curve_1 = html`<input type="text" class="ojs-hidden-ch10_ex3_histogram_density_curve" data-ojs-proxy="ch10_ex3_histogram_density_curve::var_ch10_ex3_histogram_density_curve_1" value="">`
viewof var_ch10_ex3_histogram_density_curve_2 = html`<input type="text" class="ojs-hidden-ch10_ex3_histogram_density_curve" data-ojs-proxy="ch10_ex3_histogram_density_curve::var_ch10_ex3_histogram_density_curve_2" value="">`
viewof var_ch10_ex3_histogram_density_curve_run = html`<input type="number" class="ojs-hidden-ch10_ex3_histogram_density_curve" data-ojs-run="ch10_ex3_histogram_density_curve" value="0">`Complete the script to segment the single-variable distribution of miles per gallon across discrete conditioning grids based on cylinder categories.
viewof var_ch10_ex4_faceted_histogram_1 = html`<input type="text" class="ojs-hidden-ch10_ex4_faceted_histogram" data-ojs-proxy="ch10_ex4_faceted_histogram::var_ch10_ex4_faceted_histogram_1" value="">`
viewof var_ch10_ex4_faceted_histogram_2 = html`<input type="text" class="ojs-hidden-ch10_ex4_faceted_histogram" data-ojs-proxy="ch10_ex4_faceted_histogram::var_ch10_ex4_faceted_histogram_2" value="">`
viewof var_ch10_ex4_faceted_histogram_run = html`<input type="number" class="ojs-hidden-ch10_ex4_faceted_histogram" data-ojs-run="ch10_ex4_faceted_histogram" value="0">`Complete the ggplot2 script to explicitly partition the miles per gallon variable into a predefined number of mathematical intervals.
viewof var_ch10_ex5_histogram_custom_bins_1 = html`<input type="text" class="ojs-hidden-ch10_ex5_histogram_custom_bins" data-ojs-proxy="ch10_ex5_histogram_custom_bins::var_ch10_ex5_histogram_custom_bins_1" value="">`
viewof var_ch10_ex5_histogram_custom_bins_run = html`<input type="number" class="ojs-hidden-ch10_ex5_histogram_custom_bins" data-ojs-run="ch10_ex5_histogram_custom_bins" value="0">`viewof species2 = Inputs.checkbox(
["setosa", "versicolor", "virginica"],
{ value: ["setosa", "versicolor"], label: "Species" }
);
viewof measure = Inputs.select(
["Sepal.Length","Sepal.Width","Petal.Length","Petal.Width"],
{ label: "Measure" }
);
// ===== Create flag variable =====
// ถ้า species2 เป็น null หรือ array ว่าง -> flag = 0
// ถ้ามีการเลือกอย่างน้อย 1 ค่า -> flag = 1
species_flag = (species2 && species2.length > 0) ? 1 : 0
// ===== ตรวจสอบและกำหนดค่าแทน =====
// ถ้าไม่ได้เลือกเลย → species2_clean = "No selection"
// ถ้าเลือกแล้ว → species2_clean = species2
species2_clean = (species2 && species2.length > 0) ? species2 : "No selection"We just change the function goem_histogram() to geom_density(). If you want to plot the histogram and density plot into the same graph. In the aes() function, we set the argument y = after_stat(density)
Question
From the code, if you start with a density plot and follow it with a histogram, what happens?
Example if we have to know about histogram of income between gender male and female from this data.
Question and remark
Or remove The argument position = "identity", what happens?
The argument position = "identity" is very important don’t forgot.
From the code, if you move the argument fill = gender from aes() function to geom_histogram(), what happens?
We change any color by add the scale_fill_manual() function, an the argument inside is values = <vector of color>
Remark: The order of colors follows the order of the characters or factors.
set.seed(1)
male <- rnorm(n =500, mean = 18000, sd = 2000)
female <- rnorm(n =500, mean = 25000, sd = 1500)
Data <- data.frame(gender = rep(c("male","female"), each = 500),
income = c(male, female))
Data |> ggplot() +
aes(x = income, fill = gender) +
geom_histogram( color ="black",
alpha = 0.7, bins = 30,
position = "identity") +
scale_fill_manual(values =c("blue","red")) +
theme(legend.position = "xxx")In ggplot2, a facet is a way to create multiple plots (panels) based on the levels of one or more categorical variables, allowing you to compare different subsets of the data side by side.
Faceting is especially useful when you want to visualize the same relationship across different groups in the data.
How Faceting Works
Facet by a Single Variable: You can create separate panels for each level of a single categorical variable.
Facet by Two Variables: You can create a grid of panels, where rows correspond to one variable and columns correspond to another.
This function creates a grid of panels based on two variables.
The rows correspond to levels of one variable, and the columns correspond to levels of another variable.
Useful when you want to explore the interaction between two categorical variables.
Why Use Facets
Comparison: Faceting allows you to easily compare different subsets of your data.
Clarity: By splitting data into separate panels, facets can make complex plots easier to read.
Exploration: Faceting helps explore how relationships in the data change across different groups.
Summary
Facets in ggplot2 are a powerful tool for visualizing multi-panel plots, enabling comparisons across different groups or categories in your data, faceting enhances the ability to understand complex relationships in your data by breaking them down into more manageable, comparable pieces.
Complete the data pipeline to map highway mileage using a piped structural workflow and condition the subsets row-wise by categorical cylinder values.
viewof var_ch10_ex6_basic_histogram_facets_1 = html`<input type="text" class="ojs-hidden-ch10_ex6_basic_histogram_facets" data-ojs-proxy="ch10_ex6_basic_histogram_facets::var_ch10_ex6_basic_histogram_facets_1" value="">`
viewof var_ch10_ex6_basic_histogram_facets_2 = html`<input type="text" class="ojs-hidden-ch10_ex6_basic_histogram_facets" data-ojs-proxy="ch10_ex6_basic_histogram_facets::var_ch10_ex6_basic_histogram_facets_2" value="">`
viewof var_ch10_ex6_basic_histogram_facets_run = html`<input type="number" class="ojs-hidden-ch10_ex6_basic_histogram_facets" data-ojs-run="ch10_ex6_basic_histogram_facets" value="0">`Construct a data pipeline using the native pipe operator to subset high-displacement vehicles, map discrete classes to density functions, and adjust the global layout positioning parameters.
viewof var_ch10_ex7_filtered_density_brewer_1 = html`<input type="text" class="ojs-hidden-ch10_ex7_filtered_density_brewer" data-ojs-proxy="ch10_ex7_filtered_density_brewer::var_ch10_ex7_filtered_density_brewer_1" value="">`
viewof var_ch10_ex7_filtered_density_brewer_2 = html`<input type="text" class="ojs-hidden-ch10_ex7_filtered_density_brewer" data-ojs-proxy="ch10_ex7_filtered_density_brewer::var_ch10_ex7_filtered_density_brewer_2" value="">`
viewof var_ch10_ex7_filtered_density_brewer_run = html`<input type="number" class="ojs-hidden-ch10_ex7_filtered_density_brewer" data-ojs-run="ch10_ex7_filtered_density_brewer" value="0">`Construct a multi-layered visualization pipeline. Apply vector matching logic to filter cylinder observations, partition data into a discrete grid matrix by drive type, and override global color aesthetics using custom manual value strings.
viewof var_ch10_ex8_faceted_histogram_manual_colors_1 = html`<input type="text" class="ojs-hidden-ch10_ex8_faceted_histogram_manual_colors" data-ojs-proxy="ch10_ex8_faceted_histogram_manual_colors::var_ch10_ex8_faceted_histogram_manual_colors_1" value="">`
viewof var_ch10_ex8_faceted_histogram_manual_colors_2 = html`<input type="text" class="ojs-hidden-ch10_ex8_faceted_histogram_manual_colors" data-ojs-proxy="ch10_ex8_faceted_histogram_manual_colors::var_ch10_ex8_faceted_histogram_manual_colors_2" value="">`
viewof var_ch10_ex8_faceted_histogram_manual_colors_run = html`<input type="number" class="ojs-hidden-ch10_ex8_faceted_histogram_manual_colors" data-ojs-run="ch10_ex8_faceted_histogram_manual_colors" value="0">`Construct a comprehensive ggplot2 analytics pipeline. Filter the temporal observation layer by a specific calendar year subset, split the structural viewport column-wise by manufacturing entity, and layer categorical classification vectors into aesthetic stacks mapped to a custom pastel brewer matrix.
viewof var_ch10_ex9_stacked_histogram_facets_1 = html`<input type="text" class="ojs-hidden-ch10_ex9_stacked_histogram_facets" data-ojs-proxy="ch10_ex9_stacked_histogram_facets::var_ch10_ex9_stacked_histogram_facets_1" value="">`
viewof var_ch10_ex9_stacked_histogram_facets_2 = html`<input type="text" class="ojs-hidden-ch10_ex9_stacked_histogram_facets" data-ojs-proxy="ch10_ex9_stacked_histogram_facets::var_ch10_ex9_stacked_histogram_facets_2" value="">`
viewof var_ch10_ex9_stacked_histogram_facets_run = html`<input type="number" class="ojs-hidden-ch10_ex9_stacked_histogram_facets" data-ojs-run="ch10_ex9_stacked_histogram_facets" value="0">`Construct a bounded pipeline to evaluate engine displacement limits, map historical data distribution counts onto statistical densities, and override group aesthetics manually across categorical facet panels.
viewof var_ch10_ex10_density_histogram_facets_1 = html`<input type="text" class="ojs-hidden-ch10_ex10_density_histogram_facets" data-ojs-proxy="ch10_ex10_density_histogram_facets::var_ch10_ex10_density_histogram_facets_1" value="">`
viewof var_ch10_ex10_density_histogram_facets_2 = html`<input type="text" class="ojs-hidden-ch10_ex10_density_histogram_facets" data-ojs-proxy="ch10_ex10_density_histogram_facets::var_ch10_ex10_density_histogram_facets_2" value="">`
viewof var_ch10_ex10_density_histogram_facets_run = html`<input type="number" class="ojs-hidden-ch10_ex10_density_histogram_facets" data-ojs-run="ch10_ex10_density_histogram_facets" value="0">`