8.8 Changing the Text of Tick Labels
8.8.2 Solution
Consider the scatter plot in Figure 8.15, where height is reported in inches:
library(gcookbook) # Load gcookbook for the heightweight data set
ggplot(heightweight, aes(x = ageYear, y = heightIn)) +
hw_plot <- geom_point()
hw_plot
To set arbitrary labels, as in Figure 8.15 (right), pass values to breaks and labels in the scale. One of the labels has a newline (\n
) character, which tells ggplot to put a line break there:
+
hw_plot scale_y_continuous(
breaks = c(50, 56, 60, 66, 72),
labels = c("Tiny", "Really\nshort", "Short", "Medium", "Tallish")
)
8.8.3 Discussion
Instead of setting completely arbitrary labels, it is more common to have your data stored in one format, while wanting the labels to be displayed in another. We might, for example, want heights to be displayed in feet and inches (like 5’6") instead of just inches. To do this, we can define a formatter function, which takes in a value and returns the corresponding string. For example, this function will convert inches to feet and inches:
function(x) {
footinch_formatter <- floor(x/12)
foot <- x %% 12
inch <-return(paste(foot, "'", inch, "\"", sep = ""))
}
Here’s what it returns for values 56–64 (the backslashes are there as escape characters, to distinguish the quotes in a string from the quotes that delimit a string):
footinch_formatter(56:64)
#> [1] "4'8\"" "4'9\"" "4'10\"" "4'11\"" "5'0\"" "5'1\"" "5'2\"" "5'3\""
#> [9] "5'4\""
Now we can pass our function to the scale, using the labels parameter (Figure 8.16, left):
+
hw_plot scale_y_continuous(labels = footinch_formatter)
Here, the automatic tick marks were placed every five inches, but that looks a little off for this data. We can instead have ggplot set tick marks every four inches, by specifying breaks (Figure 8.16, right):
+
hw_plot scale_y_continuous(breaks = seq(48, 72, 4), labels = footinch_formatter)
Another common task is to convert time measurements to HH:MM:SS format, or something similar. This function will take numeric minutes and convert them to this format, rounding to the nearest second (it can be customized for your particular needs):
function(x) {
timeHMS_formatter <- floor(x/60)
h <- floor(x %% 60)
m <- round(60*(x %% 1)) # Round to nearest second
s <- sprintf("%02d:%02d:%02d", h, m, s) # Format the strings as HH:MM:SS
lab <- gsub("^00:", "", lab) # Remove leading 00: if present
lab <- gsub("^0", "", lab) # Remove leading 0 if present
lab <-return(lab)
}
Running it on some sample numbers yields:
timeHMS_formatter(c(.33, 50, 51.25, 59.32, 60, 60.1, 130.23))
#> [1] "0:20" "50:00" "51:15" "59:19" "1:00:00" "1:00:06" "2:10:14"
The scales package, which is installed with ggplot2, comes with some built-in formatting functions:
comma()
adds commasto numbers, in the thousand, million, billion, etc. places.dollar()
adds a dollar sign and rounds to the nearest cent.percent()
multiplies by 100, rounds to the nearest integer, and adds a percent sign.scientific()
gives numbers in scientific notation, like3.30e+05
, for large and small numbers.
If you want to use these functions, you must first load the scales package, with library(scales)
.