In ggplot
, I often need to edit x axis labels. My normal routine is to create an additional named vector for labels (e.g., my_labels
), then use scale_x_labels(labels = my_labels)
.
Especially, this method is useful when needing to translate the labels to a different language. However, this works incorrectly when trying to wrap labels text in a Right-to-Left language.
library(dplyr)
library(ggplot2)
mpg %>%
filter(class == 'pickup' | class == "suv" | class == "compact") %>%
ggplot(aes(class, fill = factor(class))) +
geom_bar()
my_labels <-
c(
pickup = "פיקאפ",
suv = "סיובי",
compact = "קומפקטי"
)
mpg %>%
filter(class == 'pickup' | class == "suv" | class == "compact") %>%
ggplot(aes(class, fill = factor(class))) +
geom_bar() +
scale_x_discrete(labels = my_labels) # <------ this is the addition, and it works as intended
To keep it simple, I chose short Hebrew labels that don't meet wrapping criteria, but still demonstrate the fundamental problem.
library(stringr)
mpg %>%
filter(class == 'pickup' | class == "suv" | class == "compact") %>%
ggplot(aes(class, fill = factor(class))) +
geom_bar() +
scale_x_discrete(labels = str_wrap(my_labels, 10)) ## based on: https://stackoverflow.com/a/21894897/6105259
As can be seen, merely adding stringr::str_wrap()
messed up the order of labels. This problem repeats with other wrapping techniques (this one too, for example).
Any idea how I could specify external named vector for x axis labeling, and apply a text wrapping method in an RTL language (e.g., Hebrew) while preserving the correct order?
For some reason I also don't understand, str_wrap()
unnames the output, so you can't rely on the named matching anymore. Here are two solutions:
library(tidyverse)
library(stringr)
my_labels <-
c(
pickup = "פיקאפ",
suv = "סיובי",
compact = "קומפקטי"
)
mpg %>%
filter(class == 'pickup' | class == "suv" | class == "compact") %>%
ggplot(aes(class, fill = factor(class))) +
geom_bar() +
scale_x_discrete(labels = vapply(my_labels, str_wrap, character(1), width = 10))
mpg %>%
filter(class == 'pickup' | class == "suv" | class == "compact") %>%
ggplot(aes(class, fill = factor(class))) +
geom_bar() +
scale_x_discrete(labels = setNames(str_wrap(my_labels, 10), names(my_labels)))
Also note that this is not an RTL language issue:
my_labels <-
c(
pickup = "Pickup",
suv = "SUV",
compact = "Compact"
)
mpg %>%
filter(class == 'pickup' | class == "suv" | class == "compact") %>%
ggplot(aes(class, fill = factor(class))) +
geom_bar() +
scale_x_discrete(labels = str_wrap(my_labels, 10))
Also mislabels the x-axis.