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没有出现在折线图上[重复]

轴标签/标题没有出现 plotly.js

如何将 R Plotly 中的子图之间的轨迹与共享的 Y 轴链接起来,以便 hoverinfo 出现在两者上?

R语言_legend()函数用法

Plotly:如何自定义图例?