0

I'm trying to create one plot with two different scaled y-axes in ggplot2. I tried several different suggestions that I already found online, but it still does not work for my data .I've got count data as well as temperature data related to one specific month in a year:

 $ Month     : chr  "11-2016" "12-2016" "01-2017" "10-2017" ...
 $ Amount    : int  67 118 2 62 60 60 53 89 189 223 ...
 $ GroundTemp: num  3.8 0.5 -2.9 11.5 4.5 3.6 0.3 4.7 5.1 1.8 ...
 $ AirTemp   : num  3.9 0.68 -3.62 10.38 4.25 ...

I would like to create a plot, representing the month on the x-axis and the "Amount" as well as "AirTemp" on two different y-axes. Whereby the data refering to "Amount" should be represented as barplot and the "AirTemp" as a line.

That's the data set that I'm working with:

structure(list(Month = c("11-2016", "12-2016", "01-2017", "10-2017", "11-2017", "01-2018", "02-2018", "11-2018", "11-2019", "12-2019", "01-2020", "11-2020", "12-2020"), Amount = c(67L, 118L, 2L, 62L, 60L, 60L, 53L, 89L, 189L, 223L, 31L, 138L, 10L), GroundTemp = c(3.8, 0.5, -2.9, 11.5, 4.5, 3.6, 0.3, 4.7, 5.1, 1.8, 1.4, 10.3, 1.6 ), AirTemp = c(3.9, 0.68, -3.62, 10.38, 4.25, 4.3, -2.09, 4.89, 4.64, 3.01, 2.51, 9.38, 2.41)), class = "data.frame", row.names = c(NA, -13L))

I tried many different ways of getting there and I think that's the closes one:

  geom_line(aes(y=AirTemp,color="2"),linetype=1, size=2)+
  geom_point(aes(y=AirTemp, color="2"),size=4)+
  geom_line(aes(y=Amount,color="1"),linetype=1, size=2)+
  geom_point(aes(y=Amount, color="1"),size=4)

That's the resulting plot, colour 1 represents the "Amount" and colour 2 the "AirTemp"

I don't get any further than this. Could you may help me out here?

Thanks

JoëlleC
  • 1
  • 1
  • 2
    To help us to help you would you mind to add a snippet of your data via `dput()`? To post your data type `dput(NAME_OF_DATASET)` into the console and copy & paste the output starting with `structure(....` into your post. If your dataset has a lot of observations you could do `dput(head(NAME_OF_DATASET, 20))` for the first twenty rows. See also [how to make a minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – stefan Jun 28 '21 at 08:52
  • Isn't `sec_axis()` in `scale_y_...` statement working? This seems to be great to answer your problem, but as you said "I tried several different suggestions", I'm curious to know why this isn't working for you. – MonJeanJean Jun 28 '21 at 08:56
  • some examples with `sec_axis`: https://www.r-graph-gallery.com/line-chart-dual-Y-axis-ggplot2.html – Quentin Jun 28 '21 at 09:03
  • @stefan: I've added my data to the post – JoëlleC Jun 28 '21 at 09:41
  • @MonJeanJean: I'm curious as well. It seems to be problematic that I do not have data for each month, and that I only have one data point for each month... – JoëlleC Jun 28 '21 at 09:41
  • @Quentin: Thanks I'm gonna check it out – JoëlleC Jun 28 '21 at 09:41

1 Answers1

0

Try this:

  1. I ordered the Month as they appear in the data
  2. For the line you have to add the group aes as your x-axis variable is a character or factor. Otherwise you don't get a line.
  3. For the Amount I switched to geom_col
  4. I set the colors via scale_xxx_manual
  5. For the secondary axis you (probably) have to transform your data and reverse this transformation via the trans argument of sec_axis. Here I simply scaled by 20 to make the scale of AirTemp roughly the same as the one of Amount.
library(ggplot2)
library(forcats)

# Set order of Month as they appear in data
d$Month <- forcats::fct_inorder(d$Month)

ggplot(d, aes(x = Month)) +
  geom_col(aes(y = Amount, fill = "amount")) +
  geom_line(aes(y = AirTemp * 20, color = "airtemp", group = 1), linetype = 1, size = 2) +
  geom_point(aes(y = AirTemp * 20, color = "airtemp"), size = 4) +
  scale_fill_manual(values = c(amount = "blue")) +
  scale_color_manual(values = c(airtemp = "red")) +
  scale_y_continuous(sec.axis = sec_axis(trans = ~ .x / 20, name = "AirTemp"))

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51