0

Suppose I have this lovely ggplot

library(plotly)
library(tidyverse)

mpg2=mpg%>%
  filter(manufacturer%>%as.factor%>%as.numeric<6)%>%
  group_by(manufacturer,model)%>%
  summarize(hwy=mean(hwy))%>%
  mutate(model=reorder(model,hwy))

myggplot=mpg2%>%
  ggplot(aes(x=model,y=hwy))+
  geom_col()+
  coord_flip()+
  facet_grid(manufacturer~.,scales="free",space="free")+
  theme(legend.position="none",
        axis.text.y=element_text(),
        axis.title.y=element_blank(),
        axis.text.x=element_text(size=12),
        strip.text.y = element_text(angle = 0))

myggplot

enter image description here

looks good, then I try to plotlify it,

ggplotly(myggplot)

enter image description here

three problems.

  1. the facet with 1 bar only has a numeric yaxis label.
  2. the bar width is not identical across facets (my space="free" argument is lost).
  3. the labels (both y axis labels and facet labels go off-screen).

So, how do I fix it?

I also tried doing it natively, and this is what I have reached so far,

myplotly=mpg2%>%
  nest(-manufacturer)%>%
  mutate(plty=map(data,function(d){
    plot_ly(d,x=~hwy,y=~model,type="bar")   %>%
      layout(showlegend = FALSE)
  }))%>%
  select(plty)%>%
  subplot(nrows=5,shareX=T,heights = table(mpg2$manufacturer)%>%prop.table%>%unname())

myplotly

enter image description here

How would one finish it?

qoheleth
  • 2,219
  • 3
  • 18
  • 23
  • Have a look at: https://stackoverflow.com/questions/42301879/plotly-and-ggplot-with-facet-grid-in-r-how-to-to-get-yaxis-labels-to-use-tickte – Maximilian Peters Aug 14 '17 at 07:27

2 Answers2

1

I tried some manual corrections to the ggplotly output:

library(plotly)
library(tidyverse)

mpg2 <- mpg %>%
  filter(manufacturer %>% as.factor %>% as.numeric<6) %>%
  group_by(manufacturer,model) %>% summarize(hwy=mean(hwy)) %>%
  mutate(model=reorder(model,hwy))

myggplot <- mpg2 %>%  
  ggplot(aes(x=model,y=hwy)) + geom_col() +
  coord_flip() + facet_grid(manufacturer~.,scales="free",space="free") +
  theme(legend.position="none", axis.text.y=element_text(),
        axis.title.y=element_blank(), axis.text.x=element_text(size=12),
        strip.text.y = element_text(angle = 0))

# Set dimensions and margins 
g <- ggplotly(myggplot, height=800, width=1200) %>% 
 layout(autosize=F, margin=list(l=170,r=70,b=50,t=50,pad=10))

# Modify tick labels of Honda bar
g$x$layout$yaxis5$tickvals <- 1:2
g$x$layout$yaxis5$ticktext <- c("civic","")

# Modify widths of Honda and Audi bars
g$x$data[[5]]$width <- g$x$data[[5]]$width/4
g$x$data[[1]]$width <- 3*g$x$data[[1]]$width/4

# Modify positions of facet labels
for (k in seq(2,10,2)) {
  g$x$layout$shapes[[k]]$x1 <- 1.15
}
for (k in 1:6) {
  g$x$layout$annotations[[k]]$xanchor <- "center"
  g$x$layout$annotations[[k]]$x <- 1.0375
}

print(g)

The result is better than before, but not perfect.
Hope it can help you.

enter image description here

Marco Sandri
  • 23,289
  • 7
  • 54
  • 58
0

I had a similar problem and took Marco's answer a little further. I hope this will help others. Thanks.

library(ggplot2)
library(plotly, warn.conflicts=FALSE)
mtcars<-head(mtcars, n=2L)
mtcars$name<-rownames(mtcars)

p<-ggplot(data=mtcars,aes(wt,cyl))+geom_point()+facet_grid(name~carb)+
   theme(strip.text.y=element_text(angle=0, size=7),
         axis.text = element_text(size=7))
p
q <- ggplotly(p, height=700)

#Find the maximal x1 value of q's shapes. These shapes are the rectangles of the right-side facet labels.
x1<-vector()
for (k in 1:length(q$x$layout$shapes)){
  x1 <- c(x1,q$x$layout$shapes[[k]]$x1)
}
x1_to_change <- max(x1)

#Change all those maximal x1 values to something yuge:
for (k in 1:length(q$x$layout$shapes)){
  if(q$x$layout$shapes[[k]]$x1==x1_to_change){
     q$x$layout$shapes[[k]]$x1 <- 1000
  }
}

required_right_margin <- 5*max(nchar(mtcars$name))  #a tentative guesstimate

#Enlarge right margin to make space for right-side facet labels: 
q %>% layout(autosize=FALSE, margin=list(r=required_right_margin))

meehank
  • 13
  • 4
  • I was testing with different numbers of cars: mtcars<-head(mtcars, n=2L). Change the 2 to a larger number to get more cars. – meehank Dec 05 '19 at 20:14