1

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 = ",")))

Result I got:

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")

Result

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?) "inward" option

So how do I combine second and third solution so all labels are outside of the bars and visible?

1 Answers1

2

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)

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • Thanks you, this is definitely an improvment. Is there a way to "expand" panel so labels will stay inside of it and won't clatter with axis-y labels as it happened for the red bars? – Андрій zOFsky Mar 07 '21 at 20:22
  • 1
    @АндрійzOFsky not programmatically - see this unanswered question https://stackoverflow.com/questions/55686910/how-can-i-access-dimensions-of-labels-plotted-by-geom-text-in-ggplot2 – tjebo Mar 07 '21 at 20:25
  • Thank you @tjebo, you're a saviour! – Андрій zOFsky Mar 07 '21 at 20:35