在 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 及更高版本下更好地练习。
使用管道运算符%>%
和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 的答案在mtcars
和factor(cyl)
上不起作用:)
这可能是由于版本控制和修复,但是您说的两个示例现在应该不起作用!以上是关于在 R plotly 子图中,如何只显示一个图例?的主要内容,如果未能解决你的问题,请参考以下文章
如何自动显示图例,使其触及 Matlab(R 2019b)图中角落的边界?