1

I want to plot a bar graph together with a line graph (secondary axis). The observation values for the line graph appears but the line doesnt appear as shown in diagram. I think maybe my transformation is wrong? Below are my code.
enter image description here

Year <- c( "2017", "2018","2019","2020")
Response <- c(6, 10, 6, 2)
Rate <- c(0.22, 0.36, 0.21, 0.07)

df <- data.frame(month, Response,Rate)

#Chart
library(ggplot2)
ggplot(df)  + 
  geom_bar(aes(x=Year, y=Response),stat="identity", fill="yellow",colour="sienna3")+
  geom_text(aes(label=Response, x=Year, y=1.09*Response),colour="black")+
  geom_line(aes(x=Year, y=Rate*20),colour="black",stat="identity")+
  geom_text(aes(label=Rate, x=Year, y=Rate*25), colour="black")+
  scale_y_continuous("# Cases") +
  xlab("Month") +
  theme(axis.text = element_text(size = 13)) +
  theme(axis.title = element_text(size = 14)) +
  scale_y_continuous(sec.axis = sec_axis(~./25, name="Incidence rate/100000"))
Ella Taib
  • 63
  • 4
  • 2
    Just add `group = 1` inside the `geom_line()` like this : `geom_line(aes(x=Year, y=Rate*20),colour="black",stat="identity",group = 1)` which is explained in [this](https://stackoverflow.com/questions/27082601/ggplot2-line-chart-gives-geom-path-each-group-consist-of-only-one-observation) question. – maydin Jul 31 '20 at 06:20
  • Just another issue with your code, you used `scale_y_continuous` twice. The first one is replaced by the second. If you want to keep the first as well, you may need remove the first and change the second to : `scale_y_continuous(name = "# Cases", sec.axis = sec_axis(~./25, name="Incidence rate/100000"))` – Zhiqiang Wang Jul 31 '20 at 06:43
  • Your example is a bit messy. You created a variable called Year but then in the Data Frame you wrote month. In the ggplot you used Year but you called the xlab Month. – Edo Jul 31 '20 at 08:41
  • The reason why `geom_line` needs to be provided with `group = 1` is because you wrote Year as character variable. It should be a numeric variable. Remove the " " around the numbers and it will work without `group = 1`. Instead of `scale_y_continuous("# Cases") ` probably you meant `ylab("# Cases")` – Edo Jul 31 '20 at 08:43

1 Answers1

1

I tried to clean up a bit your code to solve your problem and give you out a couple of ideas on how to improve your code.

Year <- c(2017, 2018, 2019, 2020)
Response <- c(6, 10, 6, 2)
Rate <- c(0.22, 0.36, 0.21, 0.07)

df <- data.frame(Year, Response, Rate)

library(ggplot2)

correction <- 20

ggplot(df, aes(x = Year))  + 
  geom_bar (aes(y = Response), 
            stat = "identity", fill = "yellow", colour = "sienna3", alpha = 0.6)+
  geom_text(aes(y = Response, label = Response), 
            colour = "black", vjust = -0.5)+
  geom_line(aes(y = Rate * correction),
            colour = "black", size = 1)+
  geom_text(aes(y = Rate * correction, label = Rate * correction),
            colour = "black", vjust = -1)+
  ylab("# Cases") +
  xlab("Year") +
  theme(axis.text = element_text(size = 13)) +
  theme(axis.title = element_text(size = 14)) +
  scale_y_continuous(sec.axis = sec_axis(~./correction, 
                                         name = "Incidence rate/100'000")) +
  theme_minimal()

enter image description here

Notice:

  • Year is now numerical
  • I cleaned up the mess with Month and Year
  • I gave you a new idea on how to deal with the positioning of the numbers: vjust
  • I added the alpha parameter to ease up to my eyes that strong yellow :-)
  • I removed stat = "identity" from geom_line
  • I created a variable called correction to have that correction factor of yours always equal among all the transformations
  • I added a theme to make it look a bit more clean

You should add a title. Use ggtitle

Edo
  • 7,567
  • 2
  • 9
  • 19
  • this solves my problem. thank you for the succinct explanation. It looks more organized now and I can understand it easier. – Ella Taib Jul 31 '20 at 13:33