Search code examples
rggplot2plotlyggplotly

Converting ggplot object to plotly object creates axis title that overlaps tick values


I had the same issue described in this question:

R: ggplot and plotly axis margin won't change

but when I implemented the solution, I got the following error:

Warning: Ignoring unknown aesthetics: text We recommend that you use the dev version of ggplot2 with ggplotly() Install it with: devtools::install_github('hadley/ggplot2') Error in tmp[[2]] : subscript out of bounds

This code will produce this error on my machine:

library(gapminder)
library(plotly)
library(ggplot2)

lead <- rep("Fred Smith", 30)
lead <- append(lead, rep("Terry Jones", 30))
lead <- append(lead, rep("Henry Sarduci", 30))
proj_date <- seq(as.Date('2017-11-01'), as.Date('2017-11-30'), by = 'day')
proj_date <- append(proj_date, rep(proj_date, 2))
set.seed(1237)
actHrs <- runif(90, 1, 100)
cummActHrs <- cumsum(actHrs)
forHrs <- runif(90, 1, 100)
cummForHrs <- cumsum(forHrs)
df <- data.frame(Lead = lead, date_seq = proj_date,
                 cActHrs = cummActHrs,
                 cForHrs = cummForHrs)

makePlot <- function(dat=df, man_level = 'Lead') {
    p <- ggplot(dat, aes_string(x='date_seq', y='cActHrs',
                               group = man_level,
                               color = man_level),
                linetype = 1) +
         geom_line() +
         geom_line(data=df,
                   aes_string(x='date_seq', y = 'cForHrs',
                              group = man_level,
                              color = man_level),
                   linetype = 2)

    p <- p + geom_point(aes(text=sprintf('%s\nManager: %s\n MTD Actual Hrs: %s\nMTD Forecasted Hrs: %s',
                                         date_seq, Lead, round(cActHrs, 2), round(cForHrs, 2))))

    p <- p + theme_classic() + ylab('Hours') + xlab('Date')

    gp <- ggplotly(p, tooltip = "text") %>% layout(hovermode = "compare")
    ### FIX IMPLEMENTED HERE ###
    gp[['x']][['layout']][['annotations']][[2]][['x']] <- -0.1
    gp %>% layout(margin = list(l = 75))

    return(gp)
}

## run the example
p1 <- makePlot()

Solution

  • Try this:

    makePlot <- function(dat=df, man_level = "Lead") {
      dat$var <- dat[,man_level]
      dat$grp <- ""
      p <- ggplot(dat, aes(x=date_seq, y=cActHrs,
                  group = var, color = var,
                  text=paste0("Manager:", date_seq,"<br>MTD Actual Hrs:", round(cActHrs, 2),
                              "<br>MTD Forecasted Hrs:", round(cForHrs, 2))),
                  linetype = 1) +
           geom_line() +
           geom_line(data=dat,
                     aes(x=date_seq, y = cForHrs,
                         group = var, color = var),
                     linetype = 2) +
            geom_point() +
            theme_classic() + ylab("Hours") + xlab("Date") +
            scale_color_discrete(name=man_level) +
            facet_wrap(~grp)
    
        gp <- ggplotly(p, tooltip = "text") 
        # Set y-axis label position
        gp[["x"]][["layout"]][["annotations"]][[2]][["x"]] <- -0.06
        # Set legend label position    
        gp[["x"]][["layout"]][["annotations"]][[3]][["y"]] <- 0.93
        gp <- gp %>% layout(margin = list(l = 120, b=70), hovermode = "compare")
    
        return(gp)
    }
    

    enter image description here