If you’ve never coded before (or even if you have), type print("Your Name") in the interactive R chunk below and run it by hitting crtl+Enter or cmd+Enter for MAC users.
Through this tutorial you’ll learn techniques for data visualization. You’ll think about how the type of plot chosen impacts what information is conveyed (or lost). Choosing the wrong plot type can result in a useless plot (at best) or even a plot which is misleading. Think about the types (numerical, categorical) of variables you are working with and how they dictate which plot type should be utilized – for example, a scatterplot is not appropriate in every scenario!
Tutorial Objectives: After completing this tutorial you should be able to:
Grammar of Graphics: Jeffrey Gitomer said “Your grammar is a reflection of your image”. Here, we take the converse literally. Your image is a reflection of your grammar. Just like a well-written sentence follows the rules of grammar, so does an informative statistical graphic.
geom)aesthetics)In this tutorial we explore ggplot2 and think about graphics in terms of their layered grammar.
A Note on Plots: Choosing an appropriate plot is extremely important in data visualization. Some plots don’t make sense for certain variable types. For example, a scatterplot in the case of two-categorical predictors is quite a silly choice – the only thing this plot tells us is that every combination of fuel type and engine brand exists in our dataset. We have no idea which combinations are most or least popular.

The following are some recommended [basic] plots types under certain scenarios:
Throughout this tutorial, we will explore fuel efficiencies of multiple classes of vehicles using the mpg data frame.
mpg data frame by typing mpg in the following code block and running it.mpg
Notice that when you execute a line of code which just calls the name of a data frame, a snippet of that data frame is printed out. This is true for other objects (variables, vectors, functions, etc) in R as well.
Some Basic Exploratory Functions: It is useful to know more about your dataset when you first start working with data. R has a few exploratory functions which you should know about: names(mpg) prints out a list of names of your data frame’s columns, head(mpg) will show you the first six rows of the mpg dataset, dim(mpg) will show you the number of rows and columns in the dataset, and glimpse(mpg) will show you information about how R is treating the columns (int and num denote numerical values while chr and fct represent character strings and categorical variables respectively). Use the code block below to try each of these functions and use the output to answer the following questions:
The diamonds data frame is also available to you. See if you can get your basic exploratory functions to help you answer the same questions about the diamonds dataset using the code block below.
Were you able to obtain the information you were looking for? Be sure to ask a question if not!
The code below creates a plot of highway miles per gallon (hwy) against engine displacement displ (a measure of the size of an engine).
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy))

Use the plot above to answer the following questions.
A Note on Plotting Structure: Using ggplot() to create plots in R is daunting at first, but with practice you will notice the structure is very consistent and convenient!
ggplot(data = mpg) tells ggplot that the subject of our plot is the data contained in the mpg table, while the geom_point() verb tells ggplot that we want our data displayed as points (a scatterplot). The aes() inside of geom_point() tells ggplot some of the adjectives for each individual observation – here, just the location!ggplot(data = DATA) + geom_TYPE(mapping = aes(MAPPINGS))
Use the code block below to make a scatterplot of average city miles per gallon (cty) explained by engine displacement (displ).
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = cty))
Now make a scatterplot of average highway miles per gallon (hwy) exlained by number of cylinders (cyl).
Notice that this plot isn’t very useful because the cylinders variable takes on very few levels. We may be better off if we treat cyl as if it were a categorical variable here. Check out some of the other geometry layers available to you in ggplot here. Try building a set of side-by-side boxplots. If you get an error, be sure to read it – R suspects that the plot produced wasn’t the one you wanted and provides a suggestion.
ggplot(data = mpg) + geom_boxplot(mapping = aes(x = cyl, y = hwy, group = cyl))
Consider the variables for vehicle class (class) and drive type (drv) as you answer the following questions.
Use the code block below to make a useful plot of class using geom_bar() with the aesthetics x = class and fill = drv. Think about the plot you create – what does it tell you?
ggplot(data = mpg) + geom_bar(mapping = aes(x = class, fill = drv))
Note: There are many different geom types, and different aesthetic properties which can be passed to geoms. We will see examples throughout the rest of this tutorial, but reading the entirety of Chapter 3 in Hadley Wickham’s R for Data Science would be a great start for those of you who are more interested in data visualization.
Let’s go back to our original plot of hwy versus displ. Maybe we want to color the points in the scatterplot according to the class of the vehicle. Add a third aesthetic, color = class to the code below and re-run the plot.
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy))
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = class))
There’s a lot going on here, and it is hard to read. Try copying the above plotting command, but appending facet_wrap(~ class, nrow = 2) as a new layer to the plot – notice that plot layers are added with the + symbol. Again, think about the resulting plot and how it compares to your previous colored plot.
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = class))
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = class)) + facet_wrap(~ class, nrow = 2)
We’ve seen plots for categorical variables earlier in this tutorial. Let’s revisit a barplot with fill, similar to the one we constructed between class and drv earlier and check two alternative plots which give different insights. We’ll explore the transmission variable (I’ve stored a more usable version of the trans variable as trans2) and the drive variable (drv).
mpg_with_trans <- mpg
mpg_with_trans$trans2 <- str_sub(mpg_with_trans$trans, 1, -5)
We’ll switch to using the mpg_with_trans data frame for the rest of this notebook.
From the plot below we can tell that there are about twice as many vehicles in our dataset with automatic transmissions as there are with manual transmissions. The problem is that it is difficult to compare the proportions of drive types within each of these classes. We can fix this by using the position argument. Outside of aes() but still within mapping() add an argument position = "fill" to the pre-built plot – you’ll need to include a comma after aes() since commas separate arguments. Think about what is gained and lost in this new plot.
ggplot(data = mpg_with_trans) + geom_bar(mapping = aes(x = trans2, fill = drv))
ggplot(data = mpg_with_trans) + geom_bar(mapping = aes(x = trans2, fill = drv), position = "fill")
Great! But the problem now is that we’ve lost the idea that there are more automatic vehicles than there are manual vehicles in this dataset. As a third option, we can consider a mosaic plot.
mosaicplot(mpg_with_trans$trans2 ~ mpg_with_trans$drv, main = "Transmission and Drive Types")

The advantage to the mosaic plot is that it contains all of the information from the two separate plots above, but it is all combined into one plot! We’ve built a visualization that manages to convey that the proportion of manual vehicles in our dataset outweighs the proportion of automatics, and we can also compare the distribution of drive types within each of these two classes. Notice, however, that the syntax for the mosaic plot is not like the ggplot() syntax we’ve been experimenting with throughout this tutorial.
Congratulations! You made it through a first discussion on data visualization. You should know, however, that this is just the “tip of the iceberg” – there’s much more to learn. I’ve already suggested the Data Visualization chapter of Hadley Wickham’s R for Data Science, but he also has an entire book devoted to the ggplot2 package in R – check it out if you are interested in learning more!
In this tutorial you learned the following:
ggplot() follows a grammar of graphics and layered plotting structure, with “+” separating each plot layer. The structure of a ggplot is as follows:
ggplot(data = DATA) + geom_TYPE(mapping = aes(MAPPINGS))
ggplot2 documentation, or check out this cheatsheet for more inspiration!install.packages() and library() functions. You would need the ggplot2 or tidyverse libraries to run the code for this tutorial in a local R session.