Search code examples
rplotlyr-plotly

Plotly: dual y axis graph messing up line graph


I'm trying to make a dual axis plot of rainfall and temperature. I have ordered the months on the bottom, but that causes my line graph to screw up. How do I make sure the added line uses the same x axis?

temprain<-data.frame(month = c(1:12), 
   Train = c(250,220, 180,97,38,27,31,47,70,140,200,250), 
   Tair = c(17,16, 15,13,9,6,5,9,12,13,14,16))
tempseq<-seq(0,20,by=0.5)
rainseq<-seq(0,260,by=1)

xlab<-list(type = "category",
           categoryorder = "array",
           categoryarray = month.name,
           showgrid = TRUE,
           showline = TRUE,
           autorange = TRUE,
           showticklabels = TRUE,
           ticks = "outside",
           tickangle = 0
)

plot_ly(temprain) %>%
  add_bars(x = ~MonthName, y = ~Train, type = "bar", name = "Rain") %>%
  add_lines(x = ~MonthName, y = ~Tair, yaxis = "y2", name = "Temp") %>% 
  layout(xaxis = xlab,
    yaxis = list(showline = TRUE, side = "left", 
                 title = "Rainfall (mm)Temp", range = tempseq), 
    yaxis2 = list(showline = TRUE, side = "right", 
                  overlaying = "y",  title = "Air Temp (C)", range = rainseq), 
    showlegend = FALSE,  
    margin = list(pad = 0, b = 50, l = 50, r = 50)) 

I tried this as well, and it doesn't work, the temp graph disappears

plot_ly(temprain, x = ~MonthName, y = ~Tair, name = "Temp") %>%
  add_bars(x = ~MonthName, y = ~Train, yaxis = "y2", type = "bar", name = "Rain") %>%
  layout(xaxis = xlab,
    yaxis = list(showline = TRUE, side = "left", 
                 title = "Air Temp (C)", range = tempseq),  
    yaxis2 = list(showline = TRUE, side = "right", 
                  overlaying = "y",
                 title = "Rainfall (mm)", range = rainseq), 
    showlegend = FALSE,  
    margin = list(pad = 0, b = 50, l = 50, r = 50))

plot


Solution

  • Below is the solution:

    Your data:

    temprain<-data.frame(month = c(1:12), 
                         Train = c(250,220, 180,97,38,27,31,47,70,140,200,250), 
                         Tair = c(17,16, 15,13,9,6,5,9,12,13,14,16))
    

    Generate a column for month abbreviations from month:

    mymonths <- c("Jan","Feb","Mar",
                  "Apr","May","Jun",
                  "Jul","Aug","Sep",
                  "Oct","Nov","Dec")
    
    # match the month numbers against abbreviations:
    temprain$MonthAbb = mymonths[ temprain$month ]
    
    # This is the code to archieving a consistent combined graph:
    temprain$MonthAbb <- factor(temprain$MonthAbb, levels = c(as.character(temprain$MonthAbb)))
    

    Now plot your data:

    
    fig <- plot_ly(temprain)
    # Add the Train trace:
    fig <- fig %>% add_trace(x = ~MonthAbb, y = ~Train, name = "Train", type = "bar")
    
    ay <- list(
      tickfont = list(color = "red"),
      overlaying = "y",
      side = "right",
      title = "<b>Tair</b>")
    
    # Add the Tair trace:
    fig <- fig %>% add_trace(x = ~MonthAbb, y = ~Tair, name = "Tair", yaxis = "y2", mode = "lines+markers", type = "scatter")
    
    fig <- fig %>% layout(yaxis2 = ay,
      xaxis = list(title="Month"),
      yaxis = list(title="<b>Train</b>"))%>%
      layout(xaxis = list(
               zerolinecolor = '#ffff',
               zerolinewidth = 2,
               gridcolor = 'ffff'),
             yaxis = list(
               zerolinecolor = '#ffff',
               zerolinewidth = 2,
               gridcolor = 'ffff')
      )
    
    fig
    

    Output: enter image description here