ggplot(data , mapping = aes(...)) +
<GEOM_FUNCTION>(aes(...), ...) +
<OTHER_LAYERS> ggplot2
Visualizing Data with ggplot2
In the following sections, we will produce plots using the ggplot2 package, a grammar of graphics package which is also part of the tidyverse package.
The basic syntax of ggplot2 in R involves building plots step by step by adding layers with +. The general syntax is
Any plot produced using ggplot() requires the following main components:
ggplot(data, aes(...))
datais data frame that contains the data (in tidy data format) to plot,aes():aesthetics mappings (which variables are mapped to the x-axis, y-axis, color, size, shape, etc.).
+ geom_*()sepcifies the geometry that defines how the plot will be drawn (e.g., histogram, scatterplot, etc.).- Optional layer:
scale_x_continuous,scale_y_continuousto customize axes (ticks, names, scale) - Optional layer:
labs(x = ..., y = ..., subtitle = ..., title = ...)to customize the labels for the axes and plot titles - Optional layer:
ggplotthemes: e.g.,theme_classic(),theme_bw(),theme_minimal(),theme_dark(),theme_light(). Complete list here.
Examples of geom layers are:
geom_histogram(): represents numeric (continuous) data as a histogram
geom_line(): represents data as lines joining data points (e.g., line graphs)
geom_bar() : represents discrete data as a bar chart
geom_point(): represents data as points (e.g., scatter plots)
There are many ways to customize your plots by building on the basic code. As you gain more experience with R, you will discover that there are multiple ways to do things in R, including data visualizations. But, we are focussing on ggplot2 here since it is a powerful package you can use to produce impressive (and effective!) visualizations.
Numerical Variable
Let’s begin with the pfas_data data:
Suppose we are interested in the distribution of total PFAS levels for the 2023 EWG/EPA PFAS data.
QUESTION
Which of the following plots would be appropriate to visualize the distribution of total PFAS measurements? Select TRUE for all appropriate plots and FALSE otherwise.
- Histogram
- Barplot
- Dotplot
- Boxplot
- Scatterplot
Histograms
Histograms are used to show the frequency distribution of numerical data within a dataset. They are useful for understanding the spread, skewness, and the presence of any outliers in the data. We use geom_histogram to create histograms.
Try running the following code to create a histogram of PFAS levels on the cleaned dataset total_pfas_data, in which PFAS levels are stored in Value..PPT. variable.
You can also change the features of the histogram within geom_histogram:
- bin width using the
binwidthargument - bar fill colours using the
fillargument - outline colour of the bars using the
colourargument
For example:
Give it a try!
Boxplots
Boxplots show the distribution of numerial data through statistical means rather than as frequency values. The box contains the middle 50% of the data, the line in the middle of the box represents the median, while the whiskers extend to the minimum and maximum values. We use geom_boxplot to create boxplots.
Try running the following code to create a boxplot of mean PFAS levels across different states on the cleaned dataset pfas_data_mean, in which state-specific mean PFAS levels are stored in mean_ppt variable:
Note that to create this boxplot, PFAS levels were specified as y rather than x in aes() to maintain consistency with the boxplot format in the course. Try changing y to x in aes() and rerunning the code above to see what happens. Sometimes you encounter boxplots that look like this as well.
Dotplots
Dotplots also show the distribution of the data, with each observation represented as a dot. Hence, dotplots are best used when the dataset is small. We use geom_dotplot to create boxplots and dotplots.
Try running the following code to create a dotplot of mean PFAS levels across different states on the cleaned dataset pfas_data_mean, in which state-specific mean PFAS levels are stored in mean_ppt variable:
Categorical Data
Let’s begin with the cannabis_data data:
Suppose we are interested in the location distribution of the cannabis_data survey respondents:
QUESTION
Barplots
Barplots are a type of data visualization useful for comparing between groups and showing the relationship between a numerical and a categorical variable. They are highly useful for visualizing survey data!
Notice that the data type for the prov column is integer in the dataframe.
However, they are the coded representation of each province, instead of meaningful numerical values. Thus, we can use a function we learned in module 1 (i.e.,mutate) to convert the survey responses back into categories to generate a bar plot.
We use geom_bar to create bar plots. Run the following code to create a bar plot of the distribution of the provinces individuals in this cannabis_data survey fall into. factor() is used to convert the survey integer responses into more meaningful descriptions:
To change the y axis to percent instead of the default of count, you can add the code + scale_y_continuous(name="Percent",labels = scales::percent) after geom_bar(). Give it a try!
# Barplot of Percentage of individuals in each province
cannabis_data %>%
mutate(province = factor(prov, # the variable we are trying to transform
levels = 1:11, # original representation
labels = c("AB", "BC", "MB", # the corresponding transformation, e.g. 1 -> AB
"NB", "NL", "NS", "ON",
"PE", "QC", "SK", "Territories"))) %>%
ggplot(aes(x = province)) +
geom_bar() +
scale_y_continuous(name="Percent",labels = scales::percent)You can also change the features of the bar graph within geom_bar similarly as histogram. Give it a try!
# Example of changing colours
cannabis_data %>%
mutate(province = factor(prov, # the variable we are trying to transform
levels = 1:11, # original representation
labels = c("AB", "BC", "MB", # the corresponding transformation, e.g. 1 -> AB
"NB", "NL", "NS", "ON",
"PE", "QC", "SK", "Territories"))) %>%
ggplot(aes(x = province)) +
geom_bar(fill = "#56C8FC" , colour = 'blue') Multiple Variables
Using facet_wrap to show visualizations by group
Suppose we were interested in comparing cannabis usage frequency for those across different income levels. We can produce visualizions comparing the distributions of recreational cannabis usage frequencies for these groups using facet_wrap. Similar to the previous section, we first have to transform recreational_use_frequency and income_recode variables from numerical representation back to their corresponding string representation.
Using boxplots to represent multivariable data
Boxplots can also be used to represent comparisons among multiple groups. Let’s say we are interested in looking at the different concentrations of PFAS analytes vary in the state of New Jersey:
Scatterplots
Scatter plots are data visualizations used to look at the relationship between two quantitative variables. For example, we can use it to explore the association between environmental PFAS concentrations and birth weight. We use geom_point to create scatterplots. We will use the joined pfas_births dataset:
From this, we can see a moderate negative association in our data, suggesting that higher PFAS exposure may be associated with lower birth weights. Statistical tests can be used to determine whether the relationship between the variables of interest is greater than what we would expect to see by chance. However, performing statistical analysis is beyond the scope of this tutorial. If you would like to draw more attention to the association, you can create a line of best fit based on the data using geom_smooth(method = "lm"):
Coding Exercise
Now it’s time to apply the concepts we’ve gone over!
Using cannabis_data, write a code to produce a visualization that displays the distribution of cannabis recreational use frequency across different education levels.
What type of data are recreational use frequency and education level?
facet_wrap() can be used to group data
cannabis_data %>%
ggplot(aes(x = recreational_use_frequency)) +
geom_bar() +
facet_wrap(~education)Using the pfas_births data, create a data visulization of the relationship between PFAS exposure mean_ppt and fertility rate Fertility.Rate. Make sure to include meaningful axis labels!
pfas_births %>%
drop_na(mean_ppt, Fertility.Rate) %>%
ggplot(aes(x = mean_ppt, y = Fertility.Rate)) +
geom_point() +
theme_minimal() +
labs(
x = "Mean PFAS (ppt)",
y = "Fertility Rate (per 1000 female population)")