Reputation: 375
I am making a ggplot. The x-axis are factors, and the labels are long.
I can't shorten the labels, they're as short as they can be.
I am interested to make it so that labels are vertically offset. My preference would be to have every odd label at height 0, and every even at height 2 units more distant from the x-axis.
I have looked here, ggplot-hopeful-help, but have real trouble interpreting what is going on, and so can't make a useful version of this.
Any ideas??
(example code below... I'm not very good at formatting code here, it appears... sry.)
library("ggplot2");
stack <- data.frame(value =rnorm(n = 1000, sd = 2, mean=34)); stack$fact <- as.factor(rep(1:5, each=1000/5));
ggplot(stack, aes(x=fact, y=value)) + geom_boxplot(aes(fill=fact))+ scale_x_discrete(breaks=c("1", "2", "3", "4", "5"), labels=c("hi","don't suggest I shorten the text","I need long labels", "This is a long factor label","This label is very long"))
Upvotes: 3
Views: 8491
Reputation: 124213
Since guide_axis
was added in version 3.3.0
ggplot2
now offers an out-of-the-box option to place axis labels on multiple rows using the n.dogde
argument of guide_axis
:
library(ggplot2)
set.seed(123)
stack <- data.frame(value = rnorm(n = 1000, sd = 2, mean = 34))
stack$fact <- as.factor(rep(1:5, each = 1000 / 5))
ggplot(stack, aes(x = fact, y = value)) +
geom_boxplot(aes(fill = fact)) +
scale_x_discrete(
breaks = c("1", "2", "3", "4", "5"),
labels = c(
"hi", "don't suggest I shorten the text", "I need long labels",
"This is a long factor label", "This label is very long"
),
guide = guide_axis(n.dodge = 2)
)
Upvotes: 1
Reputation: 145775
Understand it or not, it seems to work pretty well. Calling the plot in your question your_plot
:
your_plot + theme(axis.text.x = element_text(vjust = grid::unit(c(-2, 0, 2), "points")))
Specifying preferences in theme()
is the way to make adjustments to the trappings of your ggplot. axis.text.x
is modifying only the x-axis text, which is created with preferences set by element_text()
. You could specify the font size, the font family, an angle for rotation, etc., in element_text()
. vjust
stands for "vertical justification", so setting the vjust
to three values, -2, 0 and 2 is applying those values to successive x-axis labels. (Apparently the negative is up, which surprised me.)
Using grid::unit()
allows us to specify the units (in this case points) by which the text is vertically moved. Looking at ?grid::units
reveals that you could use inches, cm, or several other units.
The only problem is the overlap with the x axis title. I think the easiest way to fix this is to add a couple linebreaks "\n"
before it:
your_plot +
theme(axis.text.x = element_text(vjust = grid::unit(c(-2, 0, 2), "points"))) +
labs(x = "\n\nfact")
Another solution would be to rotate the text:
your_plot + theme(axis.text.x = element_text(angle = -90, hjust = 0, vjust = 0))
For more reading, there's a whole vignette on ggplot2 theming.
Upvotes: 8
Reputation: 129
stack <- data.frame(value =rnorm(n = 1000, sd = 2, mean=34))
stack$fact <- as.factor(rep(1:5, each=1000/5))
ggplot(stack, aes(x=fact, y=value)) +
geom_boxplot(aes(fill=fact)) +
scale_x_discrete(breaks=c("1", "2", "3", "4", "5"), labels=c("hi","don't suggest I shorten the text","I need long labels", "This is a long factor label","This label is very long"))+
theme(axis.text.x = element_text(vjust = grid::unit(c(0, 2), "points"))) +
theme(axis.title.x = element_text(vjust = -0.6))
Actually the solution discussed in the link you reported required only slight modification. I also added
theme(axis.title.x = element_text(vjust = -0.6))
to lower x-axis label to prevent overlapping.
Upvotes: 0