gpt4 book ai didi

r - 在 plotly 子图中合并图例

转载 作者:行者123 更新时间:2023-12-05 09:08:20 29 4
gpt4 key购买 nike

我有几个组,每个组都有几个我测量连续值的类:

set.seed(1)

df <- data.frame(value = c(rnorm(100,1,1), rnorm(100,2,1), rnorm(100,3,1),
rnorm(100,3,1), rnorm(100,1,1), rnorm(100,2,1),
rnorm(100,2,1), rnorm(100,3,1), rnorm(100,1,1)),
class = c(rep("c1",100), rep("c2",100), rep("c3",100),
rep("c2",100), rep("c4",100), rep("c1",100),
rep("c4",100), rep("c3",100), rep("c2",100)),
group = c(rep("g1",300), rep("g2",300), rep("g3",300)))

df$class <- factor(df$class, levels =c("c1","c2","c3","c4"))
df$group <- factor(df$group, levels =c("g1","g2","g3"))

并非数据中的每个组都具有相同的类,或者换句话说,每个组都具有所有类的子集。

我正在尝试为每个组生成 R plotly 密度曲线,按类别进行颜色编码,然后使用 将它们全部组合成一个图plotlysubplot 函数。

这就是我正在做的:

library(dplyr)
library(ggplot2)
library(plotly)


set.seed(1)

df <- data.frame(value = c(rnorm(100,1,1), rnorm(100,2,1), rnorm(100,3,1),
rnorm(100,3,1), rnorm(100,1,1), rnorm(100,2,1),
rnorm(100,2,1), rnorm(100,3,1), rnorm(100,1,1)),
class = c(rep("c1",100), rep("c2",100), rep("c3",100),
rep("c2",100), rep("c4",100), rep("c1",100),
rep("c4",100), rep("c3",100), rep("c2",100)),
group = c(rep("g1",300), rep("g2",300), rep("g3",300)))

df$class <- factor(df$class, levels =c("c1","c2","c3","c4"))
df$group <- factor(df$group, levels =c("g1","g2","g3"))

plot.list <- lapply(c("g1","g2","g3"), function(g){
density.df <- do.call(rbind,lapply(unique(dplyr::filter(df, group == g)$class),function(l)
ggplot_build(ggplot(dplyr::filter(df, group == g & class == l),aes(x=value))+geom_density(adjust=1,colour="#A9A9A9"))$data[[1]] %>%
dplyr::select(x,y) %>% dplyr::mutate(class = l)))
plot_ly(x = density.df$x, y = density.df$y, type = 'scatter', mode = 'lines',color = density.df$class) %>%
layout(title=g,xaxis = list(zeroline = F), yaxis = list(zeroline = F))
})
subplot(plot.list,nrows=length(plot.list),shareX=T)

给出: enter image description here

我想解决的问题是:

  1. 让图例只出现一次(现在它对每个组重复)合并所有类
  2. 让标题出现在每个子图中,而不是只出现在最后一个图中。 (我知道我可以简单地将组名作为 x 轴标题,但我宁愿节省空间,因为实际上我有 3 个以上的组)

最佳答案

使用 plot_ly()这有点棘手,至少如果你想坚持使用 color从数据生成多条轨迹的参数。

你需要定义一个legendgroup考虑到您的类变量。这legendgroup但是不会将图例项目合并为一个(它只是将它们分组)。

相应地,为了避免图例中的重复条目,您需要设置 showlegend = FALSE对于您想隐藏的痕迹(关于图例)。

编辑:这可以通过 plotly::style 完成:

set.seed(1)

df <- data.frame(value = c(rnorm(100,1,1), rnorm(100,2,1), rnorm(100,3,1),
rnorm(100,3,1), rnorm(100,1,1), rnorm(100,2,1),
rnorm(100,2,1), rnorm(100,3,1), rnorm(100,1,1)),
class = c(rep("c1",100), rep("c2",100), rep("c3",100),
rep("c2",100), rep("c4",100), rep("c1",100),
rep("c4",100), rep("c3",100), rep("c2",100)),
group = c(rep("g1",300), rep("g2",300), rep("g3",300)))

df$class <- factor(df$class, levels =c("c1","c2","c3","c4"))
df$group <- factor(df$group, levels =c("g1","g2","g3"))

library(dplyr)
library(ggplot2)
library(plotly)

plot.list <- lapply(c("g1","g2","g3"), function(g){
density.df <- do.call(rbind,lapply(unique(dplyr::filter(df, group == g)$class),function(l)
ggplot_build(ggplot(dplyr::filter(df, group == g & class == l),aes(x=value))+geom_density(adjust=1,colour="#A9A9A9"))$data[[1]] %>%
dplyr::select(x,y) %>% dplyr::mutate(class = l)))

p <- plot_ly(data = density.df, x = ~x, y = ~y, type = 'scatter', mode = 'lines', color = ~class, legendgroup = ~class, showlegend = FALSE) %>%
layout(xaxis = list(zeroline = F), yaxis = list(zeroline = FALSE)) %>%
add_annotations(
text = g,
x = 0.5,
y = 1.1,
yref = "paper",
xref = "paper",
xanchor = "middle",
yanchor = "top",
showarrow = FALSE,
font = list(size = 15)
)
if(g == "g1"){
p <- style(p, showlegend = TRUE)
} else if(g == "g2"){
p <- style(p, showlegend = TRUE, traces = 3)
} else {
p <- style(p, showlegend = FALSE)
}
p
})

subplot(plot.list, nrows = length(plot.list), shareX = TRUE) # margin = 0.01

初始答案:这可以通过设置 showlegend = TRUE 来完成。仅针对第一个图并强制它通过虚拟数据显示所有可用的类。请看以下内容:

set.seed(1)

df <- data.frame(value = c(rnorm(100,1,1), rnorm(100,2,1), rnorm(100,3,1),
rnorm(100,3,1), rnorm(100,1,1), rnorm(100,2,1),
rnorm(100,2,1), rnorm(100,3,1), rnorm(100,1,1)),
class = c(rep("c1",100), rep("c2",100), rep("c3",100),
rep("c2",100), rep("c4",100), rep("c1",100),
rep("c4",100), rep("c3",100), rep("c2",100)),
group = c(rep("g1",300), rep("g2",300), rep("g3",300)))

df$class <- factor(df$class, levels =c("c1","c2","c3","c4"))
df$group <- factor(df$group, levels =c("g1","g2","g3"))

library(dplyr)
library(ggplot2)
library(plotly)

plot.list <- lapply(c("g1","g2","g3"), function(g){
density.df <- do.call(rbind,lapply(unique(dplyr::filter(df, group == g)$class),function(l)
ggplot_build(ggplot(dplyr::filter(df, group == g & class == l),aes(x=value))+geom_density(adjust=1,colour="#A9A9A9"))$data[[1]] %>%
dplyr::select(x,y) %>% dplyr::mutate(class = l)))

p <- plot_ly(data = density.df, x = ~x, y = ~y, type = 'scatter', mode = 'lines', color = ~class, legendgroup = ~class, showlegend = FALSE) %>%
layout(xaxis = list(zeroline = F), yaxis = list(zeroline = FALSE)) %>%
add_annotations(
text = g,
x = 0.5,
y = 1.1,
yref = "paper",
xref = "paper",
xanchor = "middle",
yanchor = "top",
showarrow = FALSE,
font = list(size = 15)
)
if(g == "g1"){
dummy_df <- data.frame(class = unique(df$class))
dummy_df$x <- density.df$x[1]
dummy_df$y <- density.df$y[1]
p <- add_trace(p, data = dummy_df, x = ~x, y = ~y, color = ~class, type = "scatter", mode = "lines", showlegend = TRUE, legendgroup = ~class, hoverinfo = 'none')
}
p
})

subplot(plot.list, nrows = length(plot.list), shareX = TRUE)

result

另一种方法(避免虚拟数据解决方法)是在循环中创建每个跟踪(或通过 lapply)并根据项目的第一次出现来控制它的图例可见性。

此外,我认为应该可以使用 ?plotly::style 来控制图例项目的可见性。 .但是,我目前无法控制单个痕迹。我提出了一个问题 here .

关于子图的标题,请参阅 this .

关于r - 在 plotly 子图中合并图例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63627563/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com