2

The simlified issue is as follows:

library(dplyr)
library(ggplot2)

data.frame(x=c(1,10,100,1000,10000), nms = c("A","B","C","D","E")) %>% 
  ggplot(aes(x=x, y=nms)) + 
  geom_bar(stat = "identity") + 
  geom_text(aes(label = x), 
            vjust = 0.5, hjust = -0.1, color = "gray")

enter image description here

As it is seen here the digits of the geom_text are not displayed for certain values. I manually set the limits for the x axis for instance by adding + scale_x_continuous(limits=c(0,11000)). But it seems not a good practice as the value of the upper limit is set randomly. Scaling up the upper limit by for example 10% max(x)*1.1 is not a solution asd well as 10% is a random number especially if it is expected that log trans can be added (or not added) to the x scale depending upon the specific values for different datasets used for the same visualisation and thus it does not take into account the width of the printed text label.

So my question is: what is the proper solution to add these geom_text geoms?

asd-tm
  • 3,381
  • 2
  • 24
  • 41
  • 1
    Don't think there is an easy or "proper" approach. But see https://stackoverflow.com/questions/75098826/automatically-leave-enough-room-for-a-label-next-to-a-barplot/75099898#75099898 for an approach to automatically adjust the limits. – stefan May 26 '23 at 14:28

1 Answers1

1

Instead of definig the limits manualy you could use the expand arg. The default is 5% on each side so expand = expansion(mult = c(0.05, 0.1)) should do the trick.

data.frame(x=c(1,10,100,1000,10000), nms = c("A","B","C","D","E")) %>% 
    ggplot(aes(x=x, y=nms)) + 
    geom_bar(stat = "identity") + 
    geom_text(aes(label = x), 
              vjust = 0.5, hjust = -0.1, color = "gray") + 
    scale_x_continuous(expand = expansion(mult = c(0.05,0.1)))

We could make the text go "inward" with hjust = "inward"

library(dplyr)
library(ggplot2)

data.frame(x=c(1,10,100,1000,10000), nms = c("A","B","C","D","E")) %>% 
  ggplot(aes(x=x, y=nms)) + 
  geom_bar(stat = "identity") + 
  geom_text(aes(label = x), 
            vjust = 0.5, hjust = "inward", color = "gray")

Or we could turn off clip with coord_cartesian(clip = 'off')

data.frame(x=c(1,10,100,1000,10000), nms = c("A","B","C","D","E")) %>% 
ggplot(aes(x=x, y=nms)) + 
  geom_bar(stat = "identity") + 
  geom_text(aes(label = x), 
            vjust = 0.5, hjust = -0.1, color = "gray")+
  coord_cartesian(clip = 'off')

It may be necessary to adjust plot margins.


data.frame(x=c(1,10,100,1000,10000), nms = c("A","B","C","D","E")) %>% 
  ggplot(aes(x=x, y=nms)) + 
  geom_bar(stat = "identity") + 
  geom_text(aes(label = x), 
            vjust = 0.5, hjust = -0.1, color = "gray") +
  theme(plot.margin = unit(c(1,1,1,1),'cm')) +
  coord_cartesian(clip = 'off')

Created on 2023-05-26 with reprex v2.0.2

M Aurélio
  • 830
  • 5
  • 13