library(tidyverse)

By default, R cuts the data into 30 bins, but then the bins won’t necessarily have a logical width. Like the column around 20 here shows the count of values between something like 19.1 and 20.3 or something

ggplot(mpg, aes(x = hwy)) +
  geom_histogram(color = "white")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

If you set a specific bin width, each column now has a more logical range. The column at 20 here shows the count of cars with between 19-21 MPG:

ggplot(mpg, aes(x = hwy)) +
  geom_histogram(binwidth = 2, color = "white")

Without setting the boundary argument, the columns are centered at their main values—like, the column for 20 includes data for 19-21; the column for 22 includes data for 21-23, etc. If you set the boundary to some value like 20 (or 10, or even 0), it’ll make it so that the column edge starts at that number:

ggplot(mpg, aes(x = hwy)) +
  geom_histogram(binwidth = 2, boundary = 10, color = "white")

So now the column at 20 shows the count of cars that are between 20-22, then 22-24, then 24-26, and so on. The left edge of the bars starts at 10