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

Posted

技术标签:

【中文标题】在 R plotly 子图中,如何只显示一个图例?【英文标题】:In R plotly subplot graph, how to show only one legend? 【发布时间】:2017-02-18 06:39:38 【问题描述】:

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

我试过这个:

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 开始,我有两个。

有什么想法吗?

【问题讨论】:

你的packageVersion("plotly") 是什么?我得到了‘4.5.2’ - 似乎按预期工作(=> 一个图例或没有图例) @lukeA :与您的版本相同,但我还不清楚:我期望仅获得 p2 情节的图例。据我了解,您得到的结果与我相同。 啊,现在我明白了。您想要一个具有独特 Species 值的图例,而现在,它们翻了一番。但是,我不知道如何实现。 【参考方案1】:

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

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

    在绘图序列后面找到的布局选项将覆盖在序列前面找到的选项。

    换句话说,布局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)
    

    在 plotly 4.0 及更高版本下更好地练习。 使用管道运算符%&gt;%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)
    

这种做法可以让您更好地了解跟踪在情节中的工作原理。您可以看到数据首先按 Species 分组,传递给 plot_ly() 函数 - 初始化绘图 - 然后您指定跟踪类型(标记)以实际绘制绘图。 当您想要添加或删除跟踪及其各自的选项、添加分组变量或拆分/汇总表时,这样编写代码会更容易。

【讨论】:

【参考方案2】:

上面的答案导致了一个小问题。图例仅与第一个图交互。您需要将图例组添加到 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)

【讨论】:

谢谢,太好了!我确切地说您的数据排序方式很重要:如果您按 p1 的物种和 p2 的 rev(species) 对数据进行排序,图形是相同的,但是当您取消选择某些内容时,它不会抑制相同模态左右。如果您使用相同的级别,相同的问题进行因式分解,那么重要的是顺序。这是正常的还是应该报告的错误?【参考方案3】:

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

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

它只会显示 p2 的图例。希望这行得通。

【讨论】:

【参考方案4】:

到目前为止,给出的答案似乎有些不确定。

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

    您的数据框已按分组变量排序(幸运的是 iris 数据已按 Species 排序), 您使用的变量不包含缺失值 (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)

以下示例无效:

    按错误变量排序:

    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)
    

    有缺失值的变量:

    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)
    

【讨论】:

我想强调“数据框必须按用作分组变量的变量排序”。刚刚花了很多时间来理解为什么@Mette 的答案在mtcarsfactor(cyl) 上不起作用:) 这可能是由于版本控制和修复,但是您说的两个示例现在应该不起作用!

以上是关于在 R plotly 子图中,如何只显示一个图例?的主要内容,如果未能解决你的问题,请参考以下文章

如何自动显示图例,使其触及 Matlab(R 2019b)图中角落的边界?

Plotly:如何使用 plotly express 在单迹散点图中显示图例?

R中子图plot_ly中每个图附近的图例

线子图(时间序列)中的注释(图例文本)

如何在 Plotly 的图中定位图例

R图中未显示图例[关闭]