We can start by using the function ggplot() to define a plot object. Set storm as the input data for ggplot():
Code
ggplot(data = storms)
. . . ::: {.smaller} Well, that doesn’t look like much. 🤔
This is the first step in creating a plot that we can add layers to. Parameters set with ggplot() can be “inherited” by layers added later. :::
3.6 Add aesthetics and layers
Set mapping with aes()
Next, we can set the mapping using the aes() function. We can start by mapping long (longitude) to x and lat (latitude) to y:
Code
ggplot(data = storms,mapping =aes(x = long,y = lat ))
Before we can see any data, we need to tell ggplot() how we want to represent the data using layers.
Layers in {ggplot2} are most often added using “geoms” (short for geometry) functions like geom_point(), geom_col(), or geom_histogram().
Let’s give it a try using geom_point():
Code
ggplot(data = storms,mapping =aes(x = long,y = lat )) +geom_point()
You can define the data and mapping parameters globally using ggplot() or locally for a single geom function. This code does the exact same thing as the prior block:
Notice that we are combining the ggplot() and geom_point() functions using the + operator. This is a style of function or operator known as an infix operator.
Next week, we will introduce a similar function known as a pipe, %>% or |> that works to pass the output from one function (or line of code) into the next line as the first parameter in a function.
For example, see how we can use a series of pipes to operate on the storms data:
The first parameter for ggplot() is data and the first parameter for all geom functions is mapping so you often see these passed as unnnamed parameters:
Code
ggplot(storms) +geom_point(aes(x = long,y = lat ) )
You can even leave off the x and y parameter names:
Code
ggplot(storms) +geom_point(aes(long, lat))
4 Mapping variables are not strings!
The variables passed to aes() don’t have quotes around them! This is because aes() is a data-masking (also known as a quoting function) where the inputs are evaluated in the context of the data.
TLDR: only put quotes around your aesthetic mappings when you want to pass a literal string.
Next we can map one of the variables (status or storm classification) to an aesthetic (color):
Code
ggplot(storms) +geom_point(aes(long, lat, color = status))
Note that we now have a legend, added automatically when we defined a mapping to color. Since color is not a “positional aesthetic” we can’t easily interpret the meaning of the graphic without a legend, labels, or annotations.
In addition to having mapped aesthetics, we can also have “fixed” aesthetics (fixed because the same value is used for every observation in the plot). When you have a lot of overlapping features (known as overplotting), you may want to reduce the alpha (or transparency) of the features:
Fixed aesthetics should be defined for each geom—they are ignored if you pass them to ggplot().
Aesthetics can also be defined using a function. In this example, we are using the boolean operator == to compare the values from “status” to the string “hurricane”:
Always supply coordinates with longitude before latitude!
sf::st_as_sf() requires that you supply coordinates in lon lat order. This is also the standard order for GeoJSON files, Shapefiles, and KML files. Check out lon lat lat lon by Tom MacWright for more information.
Finally, we can look at these observations on a map:
Note, that this is another example of how we can use the pipe (|>) to move data between functions in R.
However, to really show the potential, we need some more data. Install and load the {rnaturalearth} package and then load data for the coastline and countries:
But the map is zoomed out to show the whole world—not just the north Atlantic storm observations. We can use the xlim and ylim parameters of coord_sf() to “zoom” in on a smaller area:
storms_map <- storms_map +labs(title ="Atlantic hurricanes by category, 1975-2021",caption ="Data: NOAA Atlantic hurricane database best track data via the {dplyr package}" )storms_map