9
votes

I would like to create a simple bar chart with ggplot2 and my problem is that my x variable contains long strings so the labels are overlaid.

Here are fake datas and the plot :

library(dplyr)
library(tidyr)
library(ggplot2)

set.seed(42)
datas <- data.frame(label = sprintf("aLongLabel%d", 1:8), 
           ok = sample(seq(0, 1, by = 0.1), 8, rep = TRUE)) %>% 
  mutate(err = abs(ok - 1)) %>% 
  gather(type, freq, ok, err)

datas %>% 
  ggplot(aes(x = label, y = freq)) + 
  geom_bar(aes(fill = type), stat = "identity")

enter image description here

I would like to replace the labels by shorter ones and create a legend to show the matches.

What I've tried :

I use the shape aes parameter in geo_point which will create a legend with shapes (and plots shapes that I hide with alpha = 0). Then I change the shapes with scale_shape_manual and replace the x labels with scale_x_discrete. With guides I override the alpha parameter of my shapes so they wont be invisible in the legend.

leg.txt <- levels(datas$label)
x.labels <- structure(LETTERS[seq_along(leg.txt)], 
                      .Names = leg.txt)

datas %>% 
  ggplot(aes(x = label, y = freq)) + 
  geom_bar(aes(fill = type), stat = "identity") + 
  geom_point(aes(shape = label), alpha = 0) + 
  scale_shape_manual(name = "Labels", values = x.labels) + 
  guides(shape = guide_legend(override.aes = list(size = 5, alpha = 1))) + 
  scale_x_discrete(name = "Label", labels = x.labels)

enter image description here

It gives me the expected output but I feel like this is very hacky.

Does ggplot2 provides a way to do this more directly ? Thanks.

1
You should rotate them instead: stackoverflow.com/questions/1330989/…user3710546
I like this a lot, but it needs a better title so people can find it. Maybe something like "Shortening ggplot labels with abbreviations". And while rotation is a good solution, sometimes this would be better.Mike Wise
If I may suggest, an angle between 30 and 45 degrees will look better.user3710546
Post it as a solution to your own problem then and mark it as correct. Makes more sense than posting it in the question.Mike Wise
Also it will stay as an open unanswered question is you leave it like this which annoys the moderators and caretakers.Mike Wise

1 Answers

2
votes

Rotation solution suggested by Pascal

Rotate the labels and align them to the edge :

datas %>% 
  ggplot(aes(x = label, y = freq)) + 
  geom_bar(aes(fill = type), stat = "identity") + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

enter image description here