Code for my bar plot:
library(ggplot2)
data <- data.frame(vars = c("pos1", "neg1", "pos2", "neg2", "pos3", "pos4"),
values = c(164182, -72705, 1023777, -75002, 756206, 564523),
sign = c("p", "n", "p", "n", "p", "p"))
ggplot(data, aes(x = values, y = vars, fill = sign)) + geom_col() +
geom_text(aes(label = format(round(values), big.mark = ",")))
Not bad, but I want labels to be just outside of the bars and be fully visible. In the example above I have them "half in half out", label for pos2 is not fully visible.
So I added hjust = "outward" in the last line:
library(ggplot2)
data <- data.frame(vars = c("pos1", "neg1", "pos2", "neg2", "pos3", "pos4"),
values = c(164182, -72705, 1023777, -75002, 756206, 564523),
sign = c("p", "n", "p", "n", "p", "p"))
ggplot(data, aes(x = values, y = vars, fill = sign)) + geom_col() +
geom_text(aes(label = format(round(values), big.mark = ",")), hjust = "outward")
Now all labels except pos1 (and why is that?) are exactly as I want them (outside) but three of them are out of bounds which is not good.
Changing "outward" to "inward" solves "out of bounds" problem, but labels are now inside of bars(except pos1, what's wrong with it?)
So how do I combine second and third solution so all labels are outside of the bars and visible?
A conditional hjust
might help. Note that hjust = "inward/outward"
means "relative to the centre of the plot" - see Hadley's comment in this discussion
scale expansion = this is manual labour. For a programmatic approach, you would need to access the geom_text dimensions, which seems very difficult - see this unanswered question
library(ggplot2)
data <- data.frame(vars = c("pos1", "neg1", "pos2", "neg2", "pos3", "pos4"),
values = c(164182, -72705, 1023777, -75002, 756206, 564523),
sign = c("p", "n", "p", "n", "p", "p"))
ggplot(data, aes(x = values, y = vars, fill = sign)) + geom_col() +
geom_text(aes(label = values),
hjust = ifelse(data$values>0,0,1))+
scale_x_continuous(expand = c(.3,0))
Created on 2021-03-07 by the reprex package (v1.0.0)