在 Plotly 散点图中对误差条进行颜色编码

6

我正在尝试使用 R plotly 创建一个森林图,我想通过对应的p值为效果大小(点)和误差线着色。

以下是玩具数据:

set.seed(1)

factors <- paste0(1:25,":age")
effect.sizes <- rnorm(25,0,1)
effect.errors <- abs(rnorm(25,0,1))
p.values <- runif(25,0,1)

这是我的尝试:

library(dplyr)
plotly::plot_ly(type='scatter',mode="markers",y=~factors,x=~effect.sizes,color=~p.values,colors=grDevices::colorRamp(c("darkred","gray"))) %>%
      plotly::add_trace(error_x=list(array=effect.errors),marker=list(color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")))) %>%
      plotly::colorbar(limits=c(0,1),len=0.4,title="P-Value") %>%
      plotly::layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=list(title="Factor",zeroline=F,showticklabels=T))

这给了我:

enter image description here

除了以下几点,这已经非常接近我想要的:

  1. 我希望误差条的颜色与效应大小相似(由相应的p值确定)。
  2. 删除colorbar下面的两个trace图例。
  3. 使y轴标签的顺序与factors相同。

有什么想法吗?

2个回答

3

好的,我需要一些时间来熟悉我的plotly技能。由于您的第一个要点最困难,因此我将反向解释您的要点。

    1. 通过在yaxis列表中使用categoryordercategoryarray来操作layout以实现这一目标(参见motos的回答here
    1. 设置showlegend=FALSE
    1. 这有点棘手。我不得不将您的第二行(误差线)移动到第一行。为其添加了一个颜色向量。将其放入plot_ly函数中。使用split允许正确的分组着色。在marker-list中添加了点的颜色。此外,我通过colorRamp p.values转换为十六进制,因为每个更简单的解决方案对我都不起作用。

结果如下:

enter image description here

代码(颜色条创建了一些问题):

### Set category order
yform <- list(categoryorder = "array",
              categoryarray = rev(factors),
              title="Factor",zeroline=F,showticklabels=T)

### set the color scale and convert it to hex
library(grDevices)
mycramp<-colorRamp(c("darkred","gray"))
mycolors<-rgb(mycramp(p.values),maxColorValue = 255)

### plot without the adjusted colorbar
library(plotly)
### Without colorbar adjustment
  plot_ly(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
          color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")),
          error_x=list(array=effect.errors,color=mycolors),split=factors,showlegend=FALSE,marker=list(color=mycolors)) %>%
      layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform)

  ### The colorbar-adjustment kicks out the original colors of the scatter points. Either you plot them over
  plot_ly(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
          color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")),
          error_x=list(array=effect.errors,color=mycolors),split=factors,showlegend=FALSE,marker=list(color=mycolors)) %>%
      layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform) %>%
  colorbar(limits=c(0,1),len=0.4,title="P-Value",inherit=FALSE) %>%
      add_trace(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
            showlegend=FALSE,marker=list(color=mycolors),inherit=FALSE) %>%
    layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform)

  ### or you try to set the colorbar before the plot. This results in some warnings
  plot_ly() %>%
  colorbar(limits=c(0,1),len=0.4,title="P-Value",inherit=FALSE) %>%
      add_trace(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
          color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")),
          error_x=list(array=effect.errors,color=mycolors),split=factors,showlegend=FALSE,marker=list(color=mycolors)) %>%
      layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform)

令人奇怪的是,这个第一点问题解决起来非常困难并且导致代码量很大,因为通常情况下plotly相当支持管道逻辑,并且您将得到使用所有add函数非常易读的代码。

例如,我期望会有一些add_errorbar函数,但显然您必须在plot_ly函数中添加误差条,并且只有在使用split函数时才能使用颜色向量来表示误差。如果有人想评论或发布一个更易读的替代答案,那将非常有趣。


1
这里有一个构建ggplot2图表并使用ggplotly的想法:
创建一个数据框:
df <- data.frame(factors = factor(factors, levels = factors), #note the order of the levels which determines the order of the y axes
                 effect.sizes = effect.sizes,
                 effect.errors = effect.errors,
                 p.values = p.values)

创建 ggplot 图表:
library(ggplot2)
library(plotly)

ggplot(df)+
  geom_vline(xintercept = 0, color = "grey50") +
  geom_point(aes(y = factors,
                 x = effect.sizes,
                 color = p.values)) +
  geom_errorbarh(aes(y = factors,
                     xmin = effect.sizes - effect.errors,
                     xmax = effect.sizes + effect.errors,
                     x = effect.sizes,
                     color = p.values)) +
  scale_color_continuous(low = "darkred", high = "gray")+
  theme_bw() +
  xlab("Effect Sizes")+
  ylab("Factors") +
  theme(panel.border = element_blank(),
        plot.margin = margin(1, 1, 1, 1, "cm")) -> p1


ggplotly(p1)

enter image description here

数据:

set.seed(1)
factors <- paste0(1:25,":age")
effect.sizes <- rnorm(25,0,1)
effect.errors <- abs(rnorm(25,0,1))
p.values <- runif(25,0,1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接