I have an R Plotly subplot graph with the issue that the trace legends are duplicates:
This is a common problem:
- Looping through R Plotly with subplot and hiding all legend except one
- How to remove duplicate legend entries w/ plotly subplots()
- Plotly subplots with shared legend in R
- Merging legends in plotly subplot
- Removing Unused Subplot in R Plotly
- Display all levels in plotly subplot legend without duplicates
Some of these have (ir)relevant answers, some don't.
The solution in essence is to force the first subplot to show the legend and disable it for all other subplots. However, the way to do this depends on the implementation, i.e. whether the subplots are generated using a list or a function. In my case I am using a function which makes it tricky to force one subplot to show the legends but not the others.
A minimum working example:
# clear env
rm(list = ls())
# libraries
library(plotly)
library(reshape2)
# prepare dataset
attach(mtcars)
mtcars$car <- rownames(mtcars)
mtcars <- melt(mtcars)
# generate plot of variable
pl <- . %>%
plot_ly(
x = ~car,
y = ~value,
type = 'scatter',
mode = 'markers',
color = I('blue'),
name = 'value',
legendgroup = 'batches',
showlegend = TRUE
) %>%
layout(
xaxis = list(
type = 'category'
),
yaxis = list(
title = ~unique(variable)
)
)
# generate subplot view
mtcars %>%
group_by(variable) %>%
do(
p = pl(.)
) %>%
subplot(
nrows = NROW(.),
shareX = TRUE,
titleY = TRUE
)
This generates the image above.
In my attempt I have been trying to use a closure with a global variable which is set to FALSE after the first subplot but it is not working as expected. All legend entries disappear despite seeing in the console it is setting the global variable correctly.
# set global showlegend variable
# we will set to FALSE after first plot
showlegend <- TRUE
# generate plot of variable
pl <- . %>%
plot_ly(
x = ~car,
y = ~value,
type = 'scatter',
mode = 'markers',
color = I('blue'),
name = 'value',
legendgroup = 'batches',
# use a closure to set showlegend
showlegend = (function(){
# echo to console
print(showlegend)
if(showlegend){
# at first plot this will run
# set to FALSE for subsequent plots
showlegend <<- FALSE
return(TRUE)
} else {
# runs for all except first
return(FALSE)
}
})()
) %>%
layout(
xaxis = list(
type = 'category'
),
yaxis = list(
title = ~unique(variable)
)
)
while the console outputs: TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
based on this I expect there to be one legend entry, but the graph shows no legend entries. Why is this not working as expected?
Is there perhaps a more efficient way to toggle the showlegend variable without a closure and global variable?