删除 R 绘图子图中的图例重复项

标签 r shiny r-plotly

我有一个 R Plotly 子图,但存在跟踪图例重复的问题:

enter image description here

这是一个常见问题:

其中一些有(不)相关的答案,有些则没有。

本质上,解决方案是强制第一个子图显示图例,并为所有其他子图禁用它。然而,执行此操作的方法取决于实现,即子图是使用列表还是函数生成。 就我而言,我使用的函数使得强制一个子图显示图例而不显示其他子图变得很棘手。

最小工作示例:

# 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
  )

这会生成上面的图像。

在我的尝试中,我一直尝试使用带有全局变量的闭包,该变量在第一个子图之后设置为 FALSE,但它没有按预期工作。尽管在控制台中看到它正确设置了全局变量,但所有图例条目都消失了。

# 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)
    )
  )

这会生成: enter image description here

控制台输出:TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE

基于此,我希望有一个图例条目,但图表显示没有图例条目。为什么这没有按预期工作?

是否有一种更有效的方法可以在没有闭包和全局变量的情况下切换 showlegend 变量?

最佳答案

在进一步思考这个问题之后,我意识到 Plotly 可能会删除单个图例条目,即当绘制多个带有图例的迹线时,仅显示图例。

事实上,当添加额外的跟踪时,图表会按预期显示图例。

enter image description here

解决方案:

# 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',
    showlegend = showlegend
  ) %>%
  add_trace(
    y = ~value,
    name = 'target',
    type='scatter', 
    mode = 'lines',
    line=list(
      color='black', 
      dash='dash'
    ),
    showlegend = (function(){
      if(showlegend){
        showlegend <<- FALSE
        return(TRUE)
      } else {
        return(FALSE)
      }
    })()
  ) %>%
  layout(
    xaxis = list(
      type = 'category'
    ),
    yaxis = list(
      title = ~unique(variable)
    )
  )

请注意,闭包必须应用于最后绘制的迹线,否则全局变量设置为 FALSE 太早。

更新:在测试过程中,我发现以下方法也有效:

showlegend = (~unique(variable) == "mpg")

或者如果您不想对变量比较进行硬编码:

showlegend = (~unique(variable) == unique(mtcars$variable)[1])

这是我现在比全局变量闭包更喜欢的方法

关于删除 R 绘图子图中的图例重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64536038/

相关文章:

r - 将knitr::kable(df) 中的列加粗

arrays - R:整数字符串矩阵到整数计数数组

r - 在 R 中使用 sapply 绘制并排图

javascript - R - 使用 DT 按行格式化

jquery - R Shiny - 通过列排序禁用数据表中的特定行

r - 使用现有绘图创建 Shiny 的下拉菜单

r - 使用 R 合并 Loop 中的表

r - ggplot2 和 plotly 悬停的日期格式

r - 过滤串扰的两个键

r - 防止隐藏一组点后调整 R `plotly` 绘图轴的大小