在 R plotly subplot 图中,如何只显示一个图例?

In R plotly subplot graph, how to show only one legend?

我有一个包含两个图表的基本子图,默认情况下都有一个图例,但我只想看到其中一个。

我试过了:

require(plotly)
p1 <- plot_ly(data=iris,x=~Sepal.Length,y=~Sepal.Width,split=~Species) %>% layout(showlegend = FALSE)
p2 <-  plot_ly(data=iris,x=~Sepal.Length,y=~Sepal.Width,split=~Species) %>% layout(showlegend = TRUE)
subplot(p1,p2)
subplot(p2,p1)

但它不起作用:似乎只处理了一个 showlegend 属性,所以如果我从 p1 开始,我有两个图例,如果我从 p2 开始,我有两个。

有什么想法吗?

我会给你两个答案,一个是直接的,一个是为了更好的实践和后代(这也有助于更好地理解问题):

  1. 直接回答:
    尝试在 plot_ly() 函数中添加 showlegend = FALSE,而不是在 layout() 函数中。如果我们查看 ?subplot 文档:

    layout options found later in the sequence of plots will override options found earlier in the sequence.

    换句话说,布局 showlegend 选项仅取自您的最后一个绘图。但是使用 plot_ly() 函数中的 showlegend 选项会影响跟踪本身,将其行为保存在 subplot 中。 您的代码现在如下所示:

    require(plotly)  
    p1 <- plot_ly(data=iris,x=~Sepal.Length,y=~Sepal.Width,split=~Species,showlegend = F)
    p2 <-  plot_ly(data=iris,x=~Sepal.Length,y=~Sepal.Width,split=~Species, showlegend = T)  
    subplot(p1,p2)
    
  2. 最好在plotly 4.0及以上版本下练习
    使用管道运算符%>%group_by()函数代替split,如下:

    p1 <-
      iris%>%
      group_by(Species)%>%
      plot_ly(x=~Sepal.Length, color= ~Species)%>%
      add_markers(y= ~Sepal.Width)
    p2 <-
      iris%>%
      group_by(Species)%>%
      plot_ly(x=~Sepal.Length, color= ~Species)%>%
      add_markers(y= ~Sepal.Width, showlegend = F)
    subplot(p1,p2)
    

这种做法可以让你更好地理解 traces 在 plotly 中的工作原理。您可以看到数据首先按 Species 分组,传递给 plot_ly() 函数 - 初始化绘图 - 然后指定跟踪类型(标记)以实际制作绘图。
当您想要添加或删除跟踪及其各自的选项、添加分组变量或 split/summarize 您的 table.

时,像这样编写代码会更容易

上面的回答导致了一个小问题。图例仅与第一个情节交互。您需要将 legendgroup 添加到 plot_ly 函数以使图例与两个图交互。

library(plotly)
p1 <-
  iris%>%
  group_by(Species)%>%
  plot_ly(x=~Sepal.Length, color= ~Species, legendgroup=~Species)%>%
  add_markers(y= ~Sepal.Width)
p2 <-
  iris%>%
  group_by(Species)%>%
  plot_ly(x=~Sepal.Length, color= ~Species, legendgroup=~Species)%>%
  add_markers(y= ~Sepal.Width, showlegend=F)
subplot(p1,p2)

目前为止给出的答案中似乎有一些不确定的地方。

首先,据我所知,数据帧分组没有任何影响。这是排序而不是分组的问题(如 Maltas comment above 所示)。因此,数据框必须按用作分组变量的变量排序。但是还有另一个陷阱仍然阻止代码工作。因此,除了所需的 legendgroup,您还必须确保

  1. 你的数据框是按你的分组变量排序的(幸运的是 iris 数据已经按 Species 排序),
  2. 您使用的变量不包含缺失值 (NA)。

因此这应该有效:

library(plotly)
p1 <-
  iris %>%
  arrange(Species) %>%
  plot_ly(x = ~Sepal.Length, color = ~Species, legendgroup = ~Species) %>%
  add_markers(y = ~Sepal.Width)
p2 <-
  iris %>%
  arrange(Species) %>%
  plot_ly(x = ~Sepal.Length, color = ~Species, legendgroup = ~Species) %>%
  add_markers(y= ~Sepal.Width, showlegend = FALSE)

subplot(p1, p2)

以下示例不起作用:

  1. 按错误的变量排序:

    p1 <-
      iris %>%
      arrange(Sepal.Length) %>%
      plot_ly(x = ~Sepal.Length, color = ~Species, legendgroup = ~Species) %>%
      add_markers(y = ~Sepal.Width)
    p2 <-
      iris%>%
      arrange(Sepal.Length) %>%
      plot_ly(x=~Sepal.Length, color= ~Species, legendgroup=~Species)%>%
      add_markers(y = ~Sepal.Width, showlegend = FALSE)
    
    subplot(p1, p2)
    
  2. 具有缺失值的变量:

    df <- iris
    df$Sepal.Length[2] <- NA
    head(df)
    
    #>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #> 1          5.1         3.5          1.4         0.2  setosa
    #> 2           NA         3.0          1.4         0.2  setosa
    #> 3          4.7         3.2          1.3         0.2  setosa
    #> 4          4.6         3.1          1.5         0.2  setosa
    #> 5          5.0         3.6          1.4         0.2  setosa
    #> 6          5.4         3.9          1.7         0.4  setosa
    
    p1 <-
      df %>%
      arrange(Species) %>%
      plot_ly(x = ~Sepal.Length, color = ~Species, legendgroup = ~Species) %>%
      add_markers(y = ~Sepal.Width)
    p2 <-
     df %>%
      arrange(Species) %>%
      plot_ly(x = ~Sepal.Length, color = ~Species, legendgroup = ~Species)%>%
      add_markers(y = ~Sepal.Width, showlegend = FALSE)
    
    subplot(p1, p2)
    

或许你可以试试一个简单的方法。 (plotly 4.9.2)

subplot(style(p1, showlegend = F), p2)

只会显示p2的图例。希望这有效。