29

How can I specify the exact number of decimal places on ggplot bar chart labels?

The data:

strefa  <- c(1:13)
a       <- c(3.453782,3.295082,3.137755,3.333333,3.500000,3.351351,3.458824,3.318681,3.694175,3.241379,3.138298,3.309524,3.380000)
srednie <- data.frame(strefa,a)

The code is:

ggplot(srednie, aes(x=factor(strefa), y=a, label=round(a, digits = 2))) +
  geom_bar(position=position_dodge(), stat="identity",  colour="darkgrey", width = 0.5) +
  theme(legend.position="none",axis.text.x = element_blank(), axis.ticks.x = element_blank(), axis.ticks.y = element_blank()) +
  geom_text(size = 4, hjust = 1.2) +
  coord_flip(ylim = c(1,6))+
  xlab("") +
  ylab("")

As you can see, on bars entitled 5 and 2 the labels are limited to the 1st decimal place. How to show 2 decimal places even if there is i.e. 3.000000 or 5.999999? In such a cases I would like to show 3.00 and 6.00.

I tried to use as a aes parameter label=round(a, digits = 2) but it doesn't work.

steveb
  • 5,382
  • 2
  • 27
  • 36
Maciej B.
  • 373
  • 1
  • 4
  • 13

1 Answers1

39

You could try the following as it rounds to two digits and prints two digits after the decimal.

ggplot(srednie, aes(x=factor(strefa), y=a, label=sprintf("%0.2f", round(a, digits = 2)))) +
  geom_bar(position=position_dodge(), stat="identity",  colour="darkgrey", width = 0.5) +
  theme(legend.position="none",axis.text.x = element_blank(), axis.ticks.x = element_blank(), axis.ticks.y = element_blank()) +
  geom_text(size = 4, hjust = 1.2) +
  coord_flip(ylim = c(1,6))+
  xlab("") +
  ylab("")

The only modification was changing your code from

round(a, digits = 2)

to

sprintf("%0.2f", round(a, digits = 2))

enter image description here

Tung
  • 26,371
  • 7
  • 91
  • 115
steveb
  • 5,382
  • 2
  • 27
  • 36
  • What if I want just 3 digits no matter of the decimals? 123.45 -> 123, 1.234 -> 1.23, 0.0121 -> 0.01, 1 -> 1.00 – skan Nov 28 '19 at 20:44
  • @skan what do you want if the input is `1234567.89` ? There are 7 digits before `.`. – steveb Nov 30 '19 at 00:10
  • :) Numbers that big don't happen in my problem. In that case I would write it with scientific format. Finally I'm using the function substr(mynumbers, 1, 4) – skan Dec 01 '19 at 01:26
  • 1
    @skan with `substr` you may have incorrect rounding at the third digit (`1.239` would become `1.23` instead of `1.24`). Something like the following would get past that `threeDigits <- function(innums, max.digit.count = 3) { ld <- sapply(strsplit(as.character(innums), "[.]"), function(x) nchar(x[1])) newnums <- round(innums, max.digit.count - ld) fmtList <- paste0("%0.", max.digit.count - ld, "f") sapply(1:length(fmtList), function(x) sprintf(fmtList[x], newnums[x])) }` – steveb Dec 01 '19 at 14:45