Plotly (R) Legend 不会出现?
Posted
技术标签:
【中文标题】Plotly (R) Legend 不会出现?【英文标题】:Plotly (R) Legend Won't Appear? 【发布时间】:2020-10-18 04:42:45 【问题描述】:我正在尝试创建一个显示两种不同数据类别的 CDF 的图,并带有一个图例来显示哪种颜色对应于哪种颜色(Plotly 版本 4.9.2.1)。出于某种原因,让传奇得以展示是一种皇家痛苦。下面是一个玩具示例,其中包含我的三个尝试——只有最后一个有效,但它是令人讨厌的做作,并且使结果数据在情节中显得误导性地密集。谁能解释一下如何做到这一点?
library(plotly)
library(magrittr)
color.dat <- runif(30)
x.mat <- matrix(0, nrow=500, ncol=30)
for (i in 1:30)
x.mat[,i] <- rnorm(500, 0, color.dat[i])
### Attempt 1, no legend appears at all ###
p <- plot_ly(showlegend=TRUE)
for (i in 1:30)
tmp.cdf <- ecdf(x.mat[,i])
p <- p %>%
add_lines(x=sort(x.mat[,i]), y=tmp.cdf(sort(x.mat[,i])),
name=ifelse(color.dat[i] > 0.5, 'A', 'B'),
showlegend=FALSE,
line=list(color=ifelse(color.dat[i] > 0.5, 'blue', 'orange')))
p <- p %>%
add_lines(x=c(0,1), y=c(0,0), name='A',
line=list(color='blue'),
showlegend=TRUE, visible=FALSE) %>%
add_lines(x=c(0,1), y=c(0,0), name='B',
line=list(color='orange'),
showlegend=TRUE, visible=FALSE)
### Attempt 2, legend entry appears only for class B (doesn't appear without invisible traces added at end) ###
p <- plot_ly(showlegend=TRUE)
a.bool <- TRUE
b.bool <- TRUE
for (i in 1:30)
tmp.cdf <- ecdf(x.mat[,i])
if (color.dat[i] > 0.5 && a.bool)
class.bool <- TRUE
a.bool <- FALSE
else
class.bool <- FALSE
if (color.dat[i] < 0.5 && b.bool)
class.bool <- TRUE
b.bool <- FALSE
else
class.bool <- FALSE
p <- p %>%
add_lines(x=sort(x.mat[,i]), y=tmp.cdf(sort(x.mat[,i])),
name=ifelse(color.dat[i] > 0.5, 'A', 'B'),
showlegend=class.bool,
line=list(color=ifelse(color.dat[i] > 0.5, 'blue', 'orange')))
p <- p %>%
add_lines(x=c(0,1), y=c(0,0), name='A',
line=list(color='blue'),
showlegend=TRUE, visible=FALSE) %>%
add_lines(x=c(0,1), y=c(0,0), name='B',
line=list(color='orange'),
showlegend=TRUE, visible=FALSE)
### Attempt 3, both legend entries appear, but plot is misleading and obscures a lot of detail ###
p <- plot_ly(showlegend=TRUE)
flat.mat.a <- c()
flat.mat.b <- c()
flat.cdf.a <- c()
flat.cdf.b <- c()
for (i in 1:30)
tmp.cdf <- ecdf(x.mat[,i])
if (color.dat[i] > 0.5)
flat.mat.a <- c(flat.mat.a, sort(x.mat[,i]))
flat.cdf.a <- c(flat.cdf.a, tmp.cdf(sort(x.mat[,i])))
else
flat.mat.b <- c(flat.mat.b, sort(x.mat[,i]))
flat.cdf.b <- c(flat.cdf.b, tmp.cdf(sort(x.mat[,i])))
p <- p %>%
add_lines(x=flat.mat.a, y=flat.cdf.a,
showlegend=TRUE, name='A',
line=list(color='blue')) %>%
add_lines(x=flat.mat.b, y=flat.cdf.b,
showlegend=TRUE, name='B',
line=list(color='orange'))
【问题讨论】:
【参考方案1】:我更喜欢用 ploty 绘制东西的方法是将数据放入数据框中。
在数据准备步骤之后,只需两行代码即可获得绘图和图例。
library(plotly)
library(tidyr)
library(dplyr)
set.seed(42)
color.dat <- runif(30)
x.mat <- matrix(0, nrow=500, ncol=30)
for (i in 1:30)
x.mat[,i] <- rnorm(500, 0, color.dat[i])
# Put the data in a dataframe
dfx <- data.frame(x.mat) %>%
tidyr::pivot_longer(everything()) %>%
arrange(name, value) %>%
mutate(id = as.integer(gsub("^X", "", name)),
color = color.dat[id],
color = ifelse(color > 0.5, 'blue', 'orange')) %>%
group_by(name) %>%
mutate(cdf = ecdf(value)(value)) %>%
ungroup()
p <- dfx %>%
group_by(name) %>%
plot_ly(showlegend=TRUE) %>%
add_lines(x = ~value, y =~cdf, color = ~color, colors = c(blue = "blue", orange = "orange"))
p
【讨论】:
这看起来很棒,谢谢!您能否就 tidyr 和 dplyr 逻辑中发生的情况添加一些解释? 嗨@Ben。当然。将矩阵转换为 df 后,pivot_longer
将 df 转换或融合为长格式,即将矩阵/df 的所有列放在一列中(默认命名为 value
)。此外,用作 id 的列名放在第二列中(默认为name
)。 2.转换成long后我先添加颜色类别。 3. 按组计算 cdf,其中名称的组或类别是 data.matrix 的列。换句话说,除了第一步我只是复制你的代码。最佳以上是关于Plotly (R) Legend 不会出现?的主要内容,如果未能解决你的问题,请参考以下文章
R ggplot:传说中的“交叉效应”(不会随着 show.legend = NA 而消失)
R - ggplot2 Legend没有出现在折线图上[重复]