如何在情节中使用多个组但仅使用定义数量的图例组
How to use multiple groups in plotly but only a defined number of legendgroups
假设我有一个由多个不同细胞组成的时间序列,我可以根据它们是否接受治疗进行拆分 - 我如何绘制所有单独的时间序列(不求平均值)但根据治疗对它们进行分组密谋?
它与 ggplot 完美配合——我知道我可以从那里使用 ggplotly——但是有完整的绘图方式吗?
这里有一些虚拟数据:
library("dplyr")
library("plotly")
cell <- c(rep("a", 10), rep("b", 10), rep("c", 10), rep("d", 10), rep("e", 10), rep("f", 10))
group <- c(rep("Untreated", 10), rep("Treated", 30), rep("Unknown", 20))
time <- rep(1:10, times=6)
value <- c(runif(60))
df <- data.frame(cell, group, time, value)
# I want this in plotly:
ggplot(df, aes(x=time, y=value, group=cell, color=group)) +
geom_line()
# For many "cells" this will explode the legend (my real data have hundreds of cells)
plot_ly(df, x=~time, y=~value, split=~cell, color=~group,
type="scatter", mode="line")
# This works but it connects the last and the first timepoint
plot_ly(df, x=~time, y=~value, group=~cell, color=~group,
type="scatter", mode="line")
我需要这个:
但是 plotly 给了我这个(很多单元格的图例组太多):
或者这个(它连接单个单元格的开始和结束):
有什么方法可以 plotly 做到这一点 - 或者我需要使用 ggplotly 吗?
编辑:
- 新的和扩展的虚拟数据
- 新地块
您可以使用 legendgroup
并通过 showlegend
隐藏重复的轨迹名称。
另见:
https://plotly.com/r/legend/#grouped-legend
编辑: @JulianStopp 修改示例数据后:
这是找到隐藏在图例中的痕迹的通用方法。抱歉切换到 data.table
但我不熟悉 dplyr
:
library(data.table)
library(plotly)
cell <- c(rep("a", 10), rep("b", 10), rep("c", 10), rep("d", 10), rep("e", 10), rep("f", 10))
group <- c(rep("Untreated", 10), rep("Treated", 30), rep("Unknown", 20))
time <- rep(1:10, times=6)
value <- c(runif(60))
DF <- data.frame(cell, group, time, value)
setDT(DF)
setorder(DF, group, cell, time)
showlegendDF <- DF[, .SD[1], by = .(group, time), .SDcols = c("cell")][, showlegend := TRUE] # find first trace for each group
DF <- showlegendDF[DF, on = c("group", "cell", "time")] # join
DF[, i := .GRP, by = .(group, cell)] # create trace indices
# set(DF, which(is.na(DF[["showlegend"]])), "showlegend", FALSE) # replace NAs with FALSE
plot_ly(DF, x=~time, y=~value, split=~cell, legendgroup = ~group, name = ~group, color = ~group,
type="scatter", mode="line") %>% style(showlegend = FALSE, traces = unique(DF[is.na(showlegend), i]))
初始答案:
library("dplyr")
library("plotly")
cell <- c(rep("a", 10), rep("b", 10), rep("c", 10))
group <- c(rep("Untreated", 10), rep("Treated", 20))
time <- c(seq(1:10), seq(1:10), seq(1:10))
value <- c(runif(30))
df <- data.frame(cell, group, time, value)
plot_ly(df, x=~time, y=~value, split=~cell, legendgroup = ~group, name = ~group, color = ~group,
type="scatter", mode="line") %>% style(showlegend = FALSE, traces = 2)
假设我有一个由多个不同细胞组成的时间序列,我可以根据它们是否接受治疗进行拆分 - 我如何绘制所有单独的时间序列(不求平均值)但根据治疗对它们进行分组密谋?
它与 ggplot 完美配合——我知道我可以从那里使用 ggplotly——但是有完整的绘图方式吗?
这里有一些虚拟数据:
library("dplyr")
library("plotly")
cell <- c(rep("a", 10), rep("b", 10), rep("c", 10), rep("d", 10), rep("e", 10), rep("f", 10))
group <- c(rep("Untreated", 10), rep("Treated", 30), rep("Unknown", 20))
time <- rep(1:10, times=6)
value <- c(runif(60))
df <- data.frame(cell, group, time, value)
# I want this in plotly:
ggplot(df, aes(x=time, y=value, group=cell, color=group)) +
geom_line()
# For many "cells" this will explode the legend (my real data have hundreds of cells)
plot_ly(df, x=~time, y=~value, split=~cell, color=~group,
type="scatter", mode="line")
# This works but it connects the last and the first timepoint
plot_ly(df, x=~time, y=~value, group=~cell, color=~group,
type="scatter", mode="line")
我需要这个:
但是 plotly 给了我这个(很多单元格的图例组太多):
或者这个(它连接单个单元格的开始和结束):
有什么方法可以 plotly 做到这一点 - 或者我需要使用 ggplotly 吗?
编辑:
- 新的和扩展的虚拟数据
- 新地块
您可以使用 legendgroup
并通过 showlegend
隐藏重复的轨迹名称。
另见: https://plotly.com/r/legend/#grouped-legend
编辑: @JulianStopp 修改示例数据后:
这是找到隐藏在图例中的痕迹的通用方法。抱歉切换到 data.table
但我不熟悉 dplyr
:
library(data.table)
library(plotly)
cell <- c(rep("a", 10), rep("b", 10), rep("c", 10), rep("d", 10), rep("e", 10), rep("f", 10))
group <- c(rep("Untreated", 10), rep("Treated", 30), rep("Unknown", 20))
time <- rep(1:10, times=6)
value <- c(runif(60))
DF <- data.frame(cell, group, time, value)
setDT(DF)
setorder(DF, group, cell, time)
showlegendDF <- DF[, .SD[1], by = .(group, time), .SDcols = c("cell")][, showlegend := TRUE] # find first trace for each group
DF <- showlegendDF[DF, on = c("group", "cell", "time")] # join
DF[, i := .GRP, by = .(group, cell)] # create trace indices
# set(DF, which(is.na(DF[["showlegend"]])), "showlegend", FALSE) # replace NAs with FALSE
plot_ly(DF, x=~time, y=~value, split=~cell, legendgroup = ~group, name = ~group, color = ~group,
type="scatter", mode="line") %>% style(showlegend = FALSE, traces = unique(DF[is.na(showlegend), i]))
初始答案:
library("dplyr")
library("plotly")
cell <- c(rep("a", 10), rep("b", 10), rep("c", 10))
group <- c(rep("Untreated", 10), rep("Treated", 20))
time <- c(seq(1:10), seq(1:10), seq(1:10))
value <- c(runif(30))
df <- data.frame(cell, group, time, value)
plot_ly(df, x=~time, y=~value, split=~cell, legendgroup = ~group, name = ~group, color = ~group,
type="scatter", mode="line") %>% style(showlegend = FALSE, traces = 2)