【问题标题】:remove legend duplicates in R plotly subplots删除 R 情节子图中的图例重复项
【发布时间】:2021-02-08 15:30:02
【问题描述】:

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

这是一个常见的问题:

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

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

一个最小的工作示例:

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

这会生成:

而控制台输出:TRUE、FALSE、FALSE、FALSE、FALSE、FALSE、FALSE、FALSE、FALSE、FALSE、FALSE

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

是否有更有效的方法来切换 showlegend 变量而不使用闭包和全局变量?

【问题讨论】:

  • Here plotly.js 的相关FR 和here r-plotly 的相关问题可以找到。

标签: r shiny r-plotly


【解决方案1】:

在考虑了更多问题后,我意识到也许 Plotly 会删除单个图例条目,即当绘制多个带有图例的轨迹时,仅显示图例。

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

解决方案:

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

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

【讨论】:

  • 不幸的是,当子图的不同组中存在重复的图例项时,这在 this 这样的情况下不起作用。以上假设所有图例项都存在于第一个子图中。
猜你喜欢
  • 2021-08-03
  • 1970-01-01
  • 2015-06-08
  • 2016-03-29
  • 1970-01-01
  • 2013-03-18
  • 2017-02-09
  • 2012-11-04
  • 1970-01-01
相关资源
最近更新 更多