Search code examples
rggplot2line-plot

Adding a secondary axis for another plot using scale_y_continous


I created some data to try my hands on some ggplot codes. I tried to create several plots that I recently learned. Unfortunately I think due to my data structure I could not draw a line chart. I will put the code down so you check. Then I tried geom_segment which worked. So I decided to explore. I then tried to plot two graphs on the same plot using scale_y_continuous.

This is where I am stuck. I get this error:

Error: Discrete value supplied to continuous scale

df <- tibble(
Month = factor(month.abb, levels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep", "Oct", "Nov", "Dec")),
AR2019 = c(40.7,36.8,74.7,84.6,137,178,67.8,45.1,115,146,50.6,26.1),
AMXT2019 = c(33,34,33.1,33.3,32.4,30.4,29.3,29,30.1,31.5,32.8,32.9),
MallInc = c(1316, 1139, 1428, 1766, 1225, 1151, 924, 908, 1292, 1418, 1171, 1373.8)
)

This is the line plot that did not work

df |> ggplot(aes(x=Month))+
  geom_line(aes(y=AR2019))

nothing plotted on the graph and it gives me this message: geom_line(): Each group consists of only one observation. ℹ Do you need to adjust the group aesthetic?

So I tried this instead and it worked perfectly

df |> 
  ggplot(aes(x=Month)) +
  geom_point(aes(y=AMXT2019)) +
  geom_segment(aes(
    y=AMXT2019, 
    xend=c(tail(Month, n=-1), NA), 
    yend=c(tail(AMXT2019, n=-1), NA))
  ) 

expected line plot

Now here is my problem. I did the geom_segment for two variables and I want to plot the two on one graph but I am stuck

p1 <- df |> 
  ggplot(aes(x=Month, label=AMXT2019)) +
  geom_point(aes(y=AR2019)) +
  geom_segment(aes(
    y=AR2019, 
    xend=c(tail(Month, n=-1), NA), 
    yend=c(tail(AR2019, n=-1), NA))
    ) 

p2 <- df |> 
  ggplot(aes(x=Month)) +
  geom_point(aes(y=AMXT2019)) +
  geom_segment(aes(
    y=AMXT2019, 
    xend=c(tail(Month, n=-1), NA), 
    yend=c(tail(AMXT2019, n=-1), NA))
  ) 

This code throws the error

Error: Discrete value supplied to continuous scale

df |> ggplot( aes(x=Month)) +
  geom_segment(aes(
    y=AR2019/3, 
    xend=c(tail(Month, n=-1), NA), 
    yend=c(tail(AR2019, n=-1), NA))
  ) +
  geom_segment(aes(
    y=AMXT2019, 
    xend=c(tail(Month, n=-1), NA), 
    yend=c(tail(AMXT2019, n=-1), NA))
    ) +
  scale_y_continuous(
    name = 'Average Annual Rainfall',
    sec.axis = sec_axis(~. *3, name = 'Monthly Temperature (°C)')
  ) 

Solution

  • We could create a helper variable Month_num. The issues arises because geom_segment is expecting numeric values for both x and xend. In your case Month is a factor therefore ggplot doesn't understand how to calculate xend.

    library(ggplot2)
    
    df |>
      mutate(Month_num = 1:12) |> 
      ggplot(aes(x=Month_num)) +
      geom_segment(aes(
        y=AR2019/3, 
        xend=c(tail(Month_num, n=-1), NA), 
        yend=c(tail(AR2019, n=-1), NA)/3
      )) +
      geom_point(aes(y=AR2019/3)) + # Add points for AR2019
      geom_segment(aes(
        y=AMXT2019, 
        xend=c(tail(Month_num, n=-1), NA), 
        yend=c(tail(AMXT2019, n=-1), NA)
      )) +
      geom_point(aes(y=AMXT2019)) + # Add points for AMXT2019
      scale_y_continuous(
        name = 'Average Annual Rainfall',
        sec.axis = sec_axis(~. *3, name = 'Monthly Temperature (°C)')
      ) +
      scale_x_continuous(breaks = 1:12, labels = month.abb)
    

    enter image description here