0

I have a plot, which displays a combination of a bar chart and a line chart. Now I want to add labels to the plot, but they are all plotted in a line instead of the right position.

Here is the df I am using:

df1 <- data.frame(cat = c("category1", "category2", "category3", 
                            "category1", "category2", "category3",
                            "category1", "category2", "category3"), 
                  source = c("a", "a", "a", "b", "b", "b", "c", "c", "c"),
                  value = c(sample (c(1000L:6000L),9, replace = FALSE)),
                  stringsAsFactors = FALSE)

And the code for the plotting:

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

ggplot(df1) +
  geom_bar(data = filter(df1, source %in% c("a", "b")), aes(cat, value, fill = source), stat="identity", position = position_dodge()) +
  geom_point(data = filter(df1, source == "c"), aes(cat, value*5000/2000, color = source))+
  geom_line(data = filter(df1, source == "c"), aes(cat, value*5000/2000, color = source , group = source)) +
  labs(x= "categories", y= "a and b (bars)") +
  scale_y_continuous(sec.axis = sec_axis(~.*2000/5000, name = "c (line)"), 
                     labels= format_format(big.mark = ".", decimal.mark = ",", scientific = FALSE)) +
  scale_fill_manual(values= c("darkseagreen4", "darkseagreen3")) +
  geom_text(aes(label=value, x = cat, y = value), vjust = 1.5, size = 3) +
  theme_light() 

Does anybody know how to get the labels in the right position?

nississippi
  • 327
  • 2
  • 17
  • 1
    __1. For the bar plot:__ In your `geom_text()` you need to use `position = position_dodge(width = 1)` and also add the same grouping as your `geom_bar()` by using `group = source` as explained here: https://stackoverflow.com/a/30635119/2699660 __2. For the line/points plot__ it's best to create a new `geom_text()`. You might face some issues due to the fact that you are using a secondary axis... – byouness May 23 '18 at 14:59

1 Answers1

1

Having two different 'plots' in a single plot will force you to also have two different ways to include the labels.

The problem of having the labels on each bar is solved using position = position_dodge2(), but this won't work with the line. Just include a new geom_text for it.

df1 <- data.frame(cat = c("category1", "category2", "category3", 
                          "category1", "category2", "category3",
                          "category1", "category2", "category3"), 
                  source = c("a", "a", "a", "b", "b", "b", "c", "c", "c"),
                  value = c(sample (c(1000L:6000L),9, replace = FALSE)),
                  stringsAsFactors = FALSE)

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

ggplot() +
  geom_col(data = filter(df1, source %in% c("a", "b")), aes(cat, value, fill = source), position = position_dodge()) +
  geom_text(data = filter(df1, source %in% c("a", "b")), aes(cat, value,label=value, group = source), vjust = 1.5, size = 3, position = position_dodge(width = 1)) +

  geom_point(data = filter(df1, source == "c"), aes(cat, value*5000/2000, color = source)) +
  geom_line(data = filter(df1, source == "c"), aes(cat, value*5000/2000, color = source , group = source)) +
  geom_text(data = filter(df1, source == "c"), aes(cat, value*5000/2000, label=value), vjust = 1.5, size = 3) +

  labs(x= "categories", y= "a and b (bars)") +
  scale_y_continuous(sec.axis = sec_axis(~.*2000/5000, name = "c (line)"), 
                     labels= format_format(big.mark = ".", decimal.mark = ",", scientific = FALSE)) +
  scale_fill_manual(values= c("darkseagreen4", "darkseagreen3")) +
  theme_light() 

Created on 2018-05-25 by the reprex package (v0.2.0).

GGamba
  • 13,140
  • 3
  • 38
  • 47
  • 1
    This is exactly what I was looking for - thanks so much! The part for the line plot works perfectly. However, I cannot find the function position_dodge2. Could you tell me the package in which I can find it? – nississippi May 24 '18 at 14:30
  • It's `ggplot2` own function, try to update the package – GGamba May 24 '18 at 14:33
  • Mhh... still the same error: Error in position_dodge2(width = 1) : could not find function "position_dodge2" – nississippi May 24 '18 at 14:40
  • 1
    It should be there. Anyway as per @byouness comment you can change that to `position_dodge()` and add `group = source` in that geom's `aes`. `geom_text(data = filter(df1, source %in% c("a", "b")), aes(cat, value,label=value, group=source), vjust = 1.5, size = 3, position = position_dodge(width = 1))` – GGamba May 24 '18 at 15:10
  • Great with your geom_text for the lineplot and the geom_text for barcharts as @byouness commented, it works! Thanks guys :) – nississippi May 25 '18 at 07:03