Search code examples
rlabelgeom-bar

R geom_bar and geom_line labels for grouped bars


I want to plot a grouped barchart with labels, but they only appear as stacked bar labels.

I am using the following libraries:

library(dplyr)
library(ggplot2)
library(scales)

In the following the dataframes I am using:

df1 <- data.frame(month = c("2017-10-01", "2017-10-01", "2017-10-01", "2017-11-01", "2017-11-01", "2017-11-01", 
                            "2017-12-01", "2017-12-01", "2017-12-01", "2018-01-01", "2018-01-01", "2018-01-01", 
                            "2018-02-01", "2018-02-01", "2018-02-01", "2018-03-01", "2018-03-01", "2018-03-01"), 
                 source = c("a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c"),
                 value1 = c(sample (c(1000L:4000L),18, replace = FALSE)),
                 stringsAsFactors = FALSE
                 )

df1$month <- as.Date(as.character(df1$month, format = "%Y%m$d"))
df1$month <- as.Date(format(df1$month, "%Y-%m-01"))
df1 <- arrange(df1, month)

df2:

df2 <- data.frame(month = c("2017-10-01", "2017-11-01", "2017-12-01", "2018-01-01", "2018-02-01", "2018-03-01"), 
                  value2 = c(sample (c(5000000L:6000000L),6, replace = FALSE)), 
                  stringsAsFactors = FALSE
                  )
df2$month <- as.Date(as.character(df2$month, format = "%Y%m$d"))
df2$month <- as.Date(format(df2$month, "%Y-%m-01"))
df2 <- arrange(df2, month)

and the code for the chart:

ggplot() +
  geom_bar(data = df1, aes(month, value1*5000000/5000, fill = source), stat="identity", position = "dodge") +
  geom_point(data = df2, aes(month, value2), color = "blue")+
  geom_line(data = df2, aes(month, value2), group = 1, color = "blue") +
  labs(x = "month", y="value2 (line)") +
  scale_y_continuous(sec.axis = sec_axis(~.*5000/5000000, name = "value1 (bars)"), 
                     labels= format_format(big.mark = ".", decimal.mark = ",", scientific = FALSE)) +
  scale_x_date(labels = date_format("%Y-%b"),
               breaks = seq(from = min(df2$month), to = max(df2$month), by = "month")) +
  scale_fill_manual(values= c("darkseagreen4","darkseagreen", "darkseagreen3", "darkseagreen2")) +
  geom_text(aes(label=df1$value1, x = df1$month, y = df1$value1*6000000/5000, group = df1$source), position = position_dodge(1.5), vjust = 1.5, size = 3) +
  geom_text(aes(label=df2$value2, x = df2$month, y = df2$value2), vjust = 1.5, size = 3, color = "grey47") +
  theme_light()

Does anybody know, what I have to change to get the labels in the right position (for grouped bars)?


Solution

  • enter image description hereUse position = position_dodge() in both geom_text() and geom_bar() with the same numerical parameter passed to position_dodge(). E.g.:

    ggplot() +
      geom_bar(data = df1, aes(month, value1*5000000/5000, fill = source), stat="identity", position = position_dodge(25)) +
      geom_point(data = df2, aes(month, value2), color = "blue")+
      geom_line(data = df2, aes(month, value2), group = 1, color = "blue") +
      labs(x = "month", y="value2 (line)") +
      scale_y_continuous(sec.axis = sec_axis(~.*5000/5000000, name = "value1 (bars)"), 
                         labels= format_format(big.mark = ".", decimal.mark = ",", scientific = FALSE)) +
      scale_x_date(labels = date_format("%Y-%b"),
                   breaks = seq(from = min(df2$month), to = max(df2$month), by = "month")) +
      scale_fill_manual(values= c("darkseagreen4","darkseagreen", "darkseagreen3", "darkseagreen2")) +
      geom_text(aes(label=df1$value1, x = df1$month, y = df1$value1*6000000/5000, group = df1$source), position = position_dodge(25), vjust = 1.5, size = 3) +
      geom_text(aes(label=df2$value2, x = df2$month, y = df2$value2), vjust = 1.5, size = 3, color = "grey47") +
      theme_light()