繁体   English   中英

Plotly (R) 图例不会出现?

[英]Plotly (R) Legend Won't Appear?

我正在尝试创建一个 plot 显示两种不同数据类别的 CDF,并带有一个图例来显示哪种颜色对应于哪种颜色(Plotly 版本 4.9.2.1)。 出于某种原因,让传奇得以展现是一种皇室痛苦。 下面是一个玩具示例,其中包含我的三个尝试——只有最后一个有效,但它是令人讨厌的做作,并且使生成的数据在 plot 中显得误导性地密集。 谁能解释如何正确地做到这一点?

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'))

我使用 ploty 绘制东西的首选方法是将数据放入 dataframe 中。

在数据准备步骤之后,只需两行代码即可获得 plot 和图例。

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

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM