Skip to main content

Section 2.5 5NG#3: Histograms

Letโ€™s consider the wind_speed variable in the weather data frame once again, but unlike with the linegraphs in Sectionย 2.4, letโ€™s say we donโ€™t care about its relationship with time, but rather we only care about how the values of wind_speed distribute. In other words:
  1. What are the smallest and largest values?
  2. What is the โ€œcenterโ€ or โ€œmost typicalโ€ value?
  3. How do the values spread out?
  4. What are frequent and infrequent values?
One way to visualize this distribution of this single variable wind_speed is to plot them on a horizontal line as we do in Figureย 2.5.1:
A dot plot showing all hourly wind speed values from the NYC weather dataset plotted along a single horizontal axis, illustrating overplotting of the many values between 0 and 40 mph.
Figure 2.5.1. Plot of hourly wind speed recordings from NYC in 2023.
This gives us a general idea of how the values of wind_speed distribute: observe that wind speeds vary from around 0 miles per hour up to around 61 miles per hour (approximately 61 kilometers per hour). There appear to be more recorded wind speeds between 0 and 20 miles per hour (mph) than outside this range. However, because of the high degree of overplotting in the points, itโ€™s hard to get a sense of exactly how many values are between, say, 10 mph and 15 mph.
What is commonly produced instead of Figureย 2.5.1 is known as a histogram. A histogram is a plot that visualizes the distribution of a numerical value as follows:
  1. We first cut up the x-axis into a series of bins, where each bin represents a range of values.
  2. For each bin, we count the number of observations that fall in the range corresponding to that bin.
  3. Then for each bin, we draw a bar whose height marks the corresponding count.
Letโ€™s drill-down on an example of a histogram, shown in Figureย 2.5.2.
Histogram of hourly wind speeds with binwidth of 5 mph and white borders between bars, showing the distribution is right-skewed with most recordings between 0 and 20 mph.
Figure 2.5.2. Example histogram.
Letโ€™s focus only on wind speeds between 10 mph and 25 mph for now. Observe that there are three bins of equal width between 10 mph and 25 mph. Thus we have three bins of width 5 mph each: one bin for the 10โ€“15 mph range, another bin for the 15โ€“20 mph range, and another bin for the 20โ€“25 mph range. Since:
  1. The bin for the 10โ€“15 mph range has a height of around 8000. In other words, around 8000 of the hourly wind speed recordings are between 10 mph and 15 mph.
  2. The bin for the 15โ€“20 mph range has a height of around 2400. In other words, around 2400 of the hourly wind speed recordings are between 15 mph and 20 mph.
  3. The bin for the 20โ€“25 mph range has a height of around 700. In other words, around 700 of the hourly wind speed recordings are between 20 mph and 25 mph.
All eight bins spanning 0 mph to 40 mph on the x-axis have this interpretation.

Subsection 2.5.1 Histograms via geom_histogram

Letโ€™s now present the ggplot() code to plot your first histogram! Unlike with scatterplots and linegraphs, there is now only one variable being mapped in aes(): the single numerical variable wind_speed. The y-aesthetic of a histogram, the count of the observations in each bin, gets computed for you automatically. Furthermore, the geometric object layer is now a geom_histogram(). After running the following code, youโ€™ll see the histogram in Figureย 2.5.3 as well as warning messages. Weโ€™ll discuss the warning messages first.
ggplot(data = weather, mapping = aes(x = wind_speed)) +
  geom_histogram()
`stat_bin()` using `bins=30`. Pick better value with `binwidth`.
Warning: Removed 1033 rows containing non-finite outside the scale range (`stat_bin()`).
Histogram of hourly wind speed values from the NYC weather dataset using 30 bins (the default). The distribution is right-skewed.
Figure 2.5.3. Histogram of hourly wind speeds at three NYC airports.
The first message is telling us that the histogram was constructed using bins = 30 for 30 equally spaced bins. This is known in computer programming as a default value; unless you override this default number of bins with a number you specify, R will choose 30 by default. Weโ€™ll see in the next section how to change the number of bins to another value than the default.
The second warning message is telling us something similar to the warning message we received when we ran the code to create a scatterplot of departure and arrival delays for Envoy Air flights in Figureย 2.3.2: that because some rows have missing NA value for wind_speed, they were omitted from the histogram. R is just giving us a friendly heads-up that this was the case.
Now letโ€™s unpack the resulting histogram in Figureย 2.5.3. Observe that values above 30 mph are rather rare. However, because of the large number of bins, itโ€™s hard to get a sense for which range of wind speeds is spanned by each bin; everything is one giant amorphous blob. So letโ€™s add white vertical borders demarcating the bins by adding a color = "white" argument to geom_histogram() and ignore the warning about setting the number of bins to a better value:
ggplot(data = weather, mapping = aes(x = wind_speed)) +
  geom_histogram(color = "white")
Histogram of hourly wind speeds with white borders between the bars, making it easier to see the boundaries of individual bins. The distribution is right-skewed.
Figure 2.5.4. Histogram of hourly wind speeds at three NYC airports with white borders.
We now have an easier time associating ranges of wind speeds to each of the bins in Figureย 2.5.4. We can also vary the color of the bars by setting the fill argument. For example, you can set the bin colors to be โ€œblue steelโ€ by setting fill = "steelblue":
ggplot(data = weather, mapping = aes(x = wind_speed)) +
  geom_histogram(color = "white", fill = "steelblue")
If youโ€™re curious, run colors() to see all possible choices of colors in R!

Subsection 2.5.2 Adjusting the bins

Observe in Figureย 2.5.4 that in the 10โ€“20 mph range there appear to be roughly 8 bins. Thus each bin has width 10 divided by 8, or 1.125 mph, which is not a very easily interpretable range to work with. Letโ€™s improve this by adjusting the number of bins in our histogram in one of two ways:
  1. By adjusting the number of bins via the bins argument to geom_histogram().
  2. By adjusting the width of the bins via the binwidth argument to geom_histogram().
Using the first method, we have the power to specify how many bins we would like to cut the x-axis up in. As mentioned in the previous section, the default number of bins is 20. We can override this default, to say 20 bins, as follows:
ggplot(data = weather, mapping = aes(x = wind_speed)) +
  geom_histogram(bins = 20, color = "white")
Using the second method, instead of specifying the number of bins, we specify the width of the bins by using the binwidth argument in the geom_histogram() layer. For example, letโ€™s set the width of each bin to be five mph.
ggplot(data = weather, mapping = aes(x = wind_speed)) +
  geom_histogram(binwidth = 5, color = "white")
We compare both resulting histograms side-by-side in Figureย 2.5.5.
Two side-by-side histograms of hourly wind speed. The left uses 20 bins, the right uses a binwidth of 5 mph. Both show a right-skewed distribution.
Figure 2.5.5. Setting histogram bins in two ways.

Checkpoint 2.5.6. Learning Check 2.14.

What does changing the number of bins from 30 to 20 tell us about the distribution of wind speeds?

Checkpoint 2.5.7. Learning Check 2.15.

Would you classify the distribution of wind speeds as symmetric or skewed in one direction or another?

Checkpoint 2.5.8. Learning Check 2.16.

What would you guess is the โ€œcenterโ€ value in this distribution? Why did you make that choice?

Checkpoint 2.5.9. Learning Check 2.17.

Subsection 2.5.3 Summary

Histograms, unlike scatterplots and linegraphs, present information on only a single numerical variable. Specifically, they are visualizations of the distribution of the numerical variable in question.