使用子图循环 R Plotly 并隐藏除一个图例之外的所有图例
Looping through R Plotly with subplot and hiding all legend except one
我需要遍历 i 个因子迭代,并且每个因子都需要绘制为子图中的一个图。我想做的是隐藏第一次迭代的图例,并使用 legendgroup 将所有图例联系在一起。这是我到目前为止所做的:
library(plotly)
library(dplyr)
mtcars %>%
mutate(vs = as.factor(vs)) %>%
group_split(cyl) %>%
lapply(function(i) {
#show.legend <- ifelse(i == 1, TRUE, FALSE)
show.legend <- if(i == 1) {TRUE} else {FALSE}
plot_ly(
data = i
,x = ~gear
,y = ~mpg
,color = ~vs
,type = "bar"
,legendgroup = ~vs
) %>%
layout(
barmode = "stack"
,showlegend = show.legend
)
}) %>%
subplot(
nrows = NROW(.)
,shareX = TRUE
,shareY = TRUE
,titleX = TRUE
,titleY = TRUE
,margin = 0.05
)
但是这会产生错误并且没有图例:
Warning messages:
1: In if (i == 1) { :
the condition has length > 1 and only the first element will be used
如果我使用 show.legend <- ifelse(i == 1, TRUE, FALSE)
(上面已注释掉),我会得到多个图例,而不仅仅是一次。
我知道我可以执行以下操作,但我需要循环执行此操作。
p1 <- plot_ly(blah, showlegend = TRUE)
p2 <- plot_ly(blah, showlegend = FALSE)
P3 <- plot_ly(blah, showlegend = FALSE)
subplot(p1,p2,p3)
我相信我没有正确调用 i 迭代。作为另一种选择,我尝试了 case_when
:
show.legend <- case_when(
i == 1 ~ TRUE
,i != 1 ~ FALSE
)
但是这会产生与 ifelse 相同的结果。
library(plotly)
library(dplyr)
## store plot as variable p
p <- mtcars %>%
mutate(vs = as.factor(vs)) %>%
group_split(cyl) %>%
lapply(function(i) {
plot_ly(
data = i
,x = ~gear
,y = ~mpg
,color = ~vs
,type = "bar"
,showlegend = TRUE ## include all legends in stored variable
) %>%
layout(
barmode = "stack"
)
}) %>%
subplot(
nrows = NROW(.)
,shareX = TRUE
,shareY = TRUE
,titleX = TRUE
,titleY = TRUE
,margin = 0.05
)
## remove unwanted legends from plot
for (i in seq(3, length(p[["x"]][["data"]]))) {
p[["x"]][["data"]][[i]][["showlegend"]] <- FALSE
}
## show plot
p
您的代码中有两个问题:
i
不是 1:3
,而是您正在通过 lapply 迭代的当前小标题(请参阅下面的 seq_along
)。
这就是您收到警告的原因:
In if (i == 1) { : the condition has length > 1 and only the first
element will be used
showlegend
需要作为 plot_ly
而非 layout
的参数,因为子图总是采用 one 中的 layout
它的地块。参见 ?subplot
及其参数 which_layout
.
layout options found later in the sequence of plots will override
options found earlier in the sequence
这是我认为你想要的:
library(plotly)
library(dplyr)
tibble_list <- mtcars %>%
mutate(vs = as.factor(vs)) %>%
group_split(cyl)
lapply(seq_along(tibble_list), function(i) {
show_legend <- if (i == 1) {TRUE} else {FALSE}
plot_ly(
data = tibble_list[[i]],
x = ~ gear,
y = ~ mpg,
color = ~ vs,
type = "bar",
legendgroup = ~ vs,
showlegend = show_legend
) %>% layout(barmode = "stack")
}) %>% subplot(
nrows = NROW(.),
shareX = TRUE,
shareY = TRUE,
titleX = TRUE,
titleY = TRUE,
margin = 0.05,
which_layout = 1
)
请找一个官方例子here。
我需要遍历 i 个因子迭代,并且每个因子都需要绘制为子图中的一个图。我想做的是隐藏第一次迭代的图例,并使用 legendgroup 将所有图例联系在一起。这是我到目前为止所做的:
library(plotly)
library(dplyr)
mtcars %>%
mutate(vs = as.factor(vs)) %>%
group_split(cyl) %>%
lapply(function(i) {
#show.legend <- ifelse(i == 1, TRUE, FALSE)
show.legend <- if(i == 1) {TRUE} else {FALSE}
plot_ly(
data = i
,x = ~gear
,y = ~mpg
,color = ~vs
,type = "bar"
,legendgroup = ~vs
) %>%
layout(
barmode = "stack"
,showlegend = show.legend
)
}) %>%
subplot(
nrows = NROW(.)
,shareX = TRUE
,shareY = TRUE
,titleX = TRUE
,titleY = TRUE
,margin = 0.05
)
但是这会产生错误并且没有图例:
Warning messages:
1: In if (i == 1) { :
the condition has length > 1 and only the first element will be used
如果我使用 show.legend <- ifelse(i == 1, TRUE, FALSE)
(上面已注释掉),我会得到多个图例,而不仅仅是一次。
我知道我可以执行以下操作,但我需要循环执行此操作。
p1 <- plot_ly(blah, showlegend = TRUE)
p2 <- plot_ly(blah, showlegend = FALSE)
P3 <- plot_ly(blah, showlegend = FALSE)
subplot(p1,p2,p3)
我相信我没有正确调用 i 迭代。作为另一种选择,我尝试了 case_when
:
show.legend <- case_when(
i == 1 ~ TRUE
,i != 1 ~ FALSE
)
但是这会产生与 ifelse 相同的结果。
library(plotly)
library(dplyr)
## store plot as variable p
p <- mtcars %>%
mutate(vs = as.factor(vs)) %>%
group_split(cyl) %>%
lapply(function(i) {
plot_ly(
data = i
,x = ~gear
,y = ~mpg
,color = ~vs
,type = "bar"
,showlegend = TRUE ## include all legends in stored variable
) %>%
layout(
barmode = "stack"
)
}) %>%
subplot(
nrows = NROW(.)
,shareX = TRUE
,shareY = TRUE
,titleX = TRUE
,titleY = TRUE
,margin = 0.05
)
## remove unwanted legends from plot
for (i in seq(3, length(p[["x"]][["data"]]))) {
p[["x"]][["data"]][[i]][["showlegend"]] <- FALSE
}
## show plot
p
您的代码中有两个问题:
i
不是1:3
,而是您正在通过 lapply 迭代的当前小标题(请参阅下面的seq_along
)。 这就是您收到警告的原因:
In if (i == 1) { : the condition has length > 1 and only the first element will be used
showlegend
需要作为plot_ly
而非layout
的参数,因为子图总是采用 one 中的layout
它的地块。参见?subplot
及其参数which_layout
.
layout options found later in the sequence of plots will override options found earlier in the sequence
这是我认为你想要的:
library(plotly)
library(dplyr)
tibble_list <- mtcars %>%
mutate(vs = as.factor(vs)) %>%
group_split(cyl)
lapply(seq_along(tibble_list), function(i) {
show_legend <- if (i == 1) {TRUE} else {FALSE}
plot_ly(
data = tibble_list[[i]],
x = ~ gear,
y = ~ mpg,
color = ~ vs,
type = "bar",
legendgroup = ~ vs,
showlegend = show_legend
) %>% layout(barmode = "stack")
}) %>% subplot(
nrows = NROW(.),
shareX = TRUE,
shareY = TRUE,
titleX = TRUE,
titleY = TRUE,
margin = 0.05,
which_layout = 1
)
请找一个官方例子here。