dan
dan

Reputation: 6314

Plotly of multiple plots with shared legend

I have a list of ggplot objects:

set.seed(1)
require(ggplot2)
pl <- lapply(1:3, function(.x) ggplot(data.frame(x=rnorm(100),y=rnorm(100),group=c(rep("a",50),rep("b",50))),aes(x=x,y=y,col=group))+geom_point())

which I want to convert to a list of plotly objects and save to html using the htmlwidgets::saveWidget.

I imagine subplot is the way to go here, like this:

require(plotly)
htmlwidgets::saveWidget(subplot(lapply(pl,function(p) ggplotly(p))),"~/pl.html")

However this comes out with the all legends printed:

enter image description here

Is there a way to have it printed with a shared legend?

Upvotes: 1

Views: 1811

Answers (2)

Maximilian Peters
Maximilian Peters

Reputation: 31729

You can manually overwrite the showlegend attribute. ggplotly creates three graphs which two traces each. The first index (p[[1]]) is the graph, the 2nd index is the trace ([['data']][[1]]).

Or more elegantly, restyle the first 4 traces:

p <- style(p = last_plot(), traces = c(1,2,3,4), showlegend = FALSE)

enter image description here

require(ggplot2)
require(plotly)
set.seed(1)

pl <- lapply(1:3, function(.x) ggplot(data.frame(x=rnorm(100),y=rnorm(100),group=c(rep("a",50),rep("b",50))),aes(x=x,y=y,col=group))+geom_point())
p <- lapply(pl,function(p) ggplotly(p))
p[[1]][['x']][['data']][[1]][['showlegend']] <- FALSE
p[[1]][['x']][['data']][[2]][['showlegend']] <- FALSE
p[[2]][['x']][['data']][[1]][['showlegend']] <- FALSE
p[[2]][['x']][['data']][[2]][['showlegend']] <- FALSE
#clears the 'group' annotation
p[[1]][['x']][['layout']][['annotations']][[1]][['text']] <- ''
p[[2]][['x']][['layout']][['annotations']][[1]][['text']] <- ''

htmlwidgets::saveWidget(subplot(p),"pl.html")

Upvotes: 1

dan
dan

Reputation: 6314

With @Maximilian Peters help:

require(ggplot2)
require(plotly)
set.seed(1)

pl <- lapply(1:3, function(.x) ggplot(data.frame(x=rnorm(100),y=rnorm(100),group=c(rep("a",50),rep("b",50))),aes(x=x,y=y,col=group))+geom_point())

pll <- lapply(1:length(pl),function(p) {
  ply <- ggplotly(pl[[p]])
  if(p < length(pl)){
    ply[['x']][['data']][[1]][['showlegend']] <- FALSE
    ply[['x']][['data']][[2]][['showlegend']] <- FALSE
    ply <- hide_legend(ply)
  }
  return(ply)
})

htmlwidgets::saveWidget(subplot(pll),"ply.html")

enter image description here

Upvotes: 1

Related Questions