3
votes

I have data with long names which i would like to plot using ggplotly.

That's my code:

library(ggplot2)
library(plotly)
temp<-data.frame(x=c("longgggggggggggggggggggggggg_nameeeeeeeeeeeeeee1", "longggggggggggggggggggggggggg_nameeeeeeeeeeeeeee2"),
                 y=c(5,10))

break_str<-function(str,n){
  if(nchar(str)<=n)
    return(str)
  ans<-""
  for(i in 1:ceiling(nchar(str)/n)){
    if(i<ceiling(nchar(str)/n)){
      ans<-paste0(ans,substr(str,start=((i-1)*n+1),stop=min(i*n,nchar(str))),"\n")
    } else{
      ans<-paste0(ans,substr(str,start=((i-1)*n+1),stop=min(i*n,nchar(str))))
    }
  }
  return(ans)
}

p <- ggplot(temp, aes(x=x, y=y)) +  
  labs(x="x",y="y") + geom_bar(stat="identity") +  coord_flip() +
  scale_x_discrete(labels = function(x) lapply(x,function(str){break_str(str,10)})) 

ggplotly(p)

As you can see I use a custom break_str function which works similar to stringr::str_wrap but still it doesn't remove the margin in the plot.

This problem doesn't show up when in the ggplot version of p.

Any help would be appreciated

Thanks

1

1 Answers

2
votes

Looks like you stumbled over a bug in ggplotly (maybe you should raise an issue on github). I had a look into the source code. The issue is that ggplotly does not take linebreaks in the tick labels into account when computing the margins. Hence, the margin is set too wide. This problem does not arise if you make the plot using plotly. However, as a simple workaround you can force automargin to do its job by adding the layout option margin = list(l = 0) like so:

ggplotly(p) %>%
  layout(
    margin = list(l = 0)
  )

which results in this plot:

enter image description here