在散点图中按一个因子分割点

问题描述 投票:0回答:2

可能很简单。

我有想要绘制的数据点(带有误差线)。 分组因素有两个级别:

group
cluster
:

set.seed(1)
df <- data.frame(cluster=rep(LETTERS[1:10],2),group=c(rep("A",10),rep("B",10)),point=rnorm(20),err=runif(20,0.1,0.3))
df$group <- factor(df$group,levels=c("A","B"))

我想绘制

x-axis
df$cluster
的点,并且在每个
cluster
内,这些点由
df$group
进行颜色编码并分割(以便
group
A
点保留为
 group
B
点)。

这就是我正在尝试的:

library(plotly)
plot_ly(x=~df$cluster,y=~df$point,split=~df$group,type='scatter',mode="markers",showlegend=T,color=~df$group) %>%
  layout(legend=list(orientation="h",xanchor="center",x=0.5,y=1),xaxis=list(title=NA,zeroline=F,categoryorder="array",categoryarray=sort(unique(df$cluster)),showticklabels=T),yaxis=list(title="Val",zeroline=F)) %>%
  plotly::add_trace(error_y=list(array=df$err),showlegend=F)

这给了我:

非常接近,但唯一不起作用的是将每个

cluster
中的点按
group
分开。

知道如何让它发挥作用吗?理想情况下,代码应该是通用的,以便在每个

cluster
内分割任意数量的组级别,而不是特定于本示例的
A
B
的代码。

r split plotly
2个回答
4
投票

我喜欢

plotly
并且几乎只使用它,但是
ggplot2
内置了一些不错的功能,需要进行一些调整才能在
plotly
中复制。

不过,我认为如果您计划发布交互式图供其他人审阅,那么真正了解一些更详细的细节是值得的。如果您使用本机语法而不是

R
ggplotly
API 提供了大量可用于调整的控制,并使每个小细节都变得完美。

话虽如此,我将如何解决这个问题:


(有问题提供数据生成代码)

library(plotly)    
set.seed(1)
df <- data.frame(cluster=rep(LETTERS[1:10],2),
                 group=c(rep("A",10),
                         rep("B",10)),
                 point=rnorm(20),
                 err=runif(20,0.1,0.3))    
df$group <- factor(df$group,levels=c("A","B"))

首先,你需要系统地自己做一些手动“抖动”。我还没有阅读在

ggplot2
函数中“自动神奇地”执行此操作的等效源代码,但我想象类似的事情正在幕后发生。

## Generate a set of offsets based on the number of group
Offset <- data.frame(group = unique(df$group),
                     offset = seq(-0.1, 0.1,length.out = length(unique(df$group))))

## Join the offset to the data frame based on group
df <- merge(df,Offset,by = "group", all.x = TRUE)

## Calculate an x location
df$x_location <- as.numeric(as.factor(df$cluster)) + df$offset

head(df)
后期处理:

  group cluster      point       err offset x_location
1     A       A -0.6264538 0.2641893   -0.1        0.9
2     A       B  0.1836433 0.2294120   -0.1        1.9
3     A       C -0.8356286 0.2565866   -0.1        2.9
4     A       D  1.5952808 0.2106073   -0.1        3.9
5     A       E  0.3295078 0.2059439   -0.1        4.9
6     A       F -0.8204684 0.2578712   -0.1        5.9

现在您有了明确的 x_location,您可以在散点图上使用它,然后使用数组添加分类刻度线/文本。然后,通过在

text
中显示感兴趣的值,您可以从
x
中消除
y
hoverinfo
值,以完全覆盖您的踪迹。

df %>% 
  plot_ly() %>% 
  add_trace(x= ~x_location,y= ~point, color= ~group,
            text = ~paste0("Group ",group," - Cluster ", cluster,"<br>",round(point,2)),
            error_y = list(type = "data", array = ~err), 
            hoverinfo = "text",
            type = "scatter", mode = "markers") %>%
  layout(hovermode = "compare",
         paper_bgcolor = 'rgba(235,235,235,0)',
         plot_bgcolor = "rgba(235,235,235,1)",
         legend=list(orientation="h",
                     xanchor="center",
                     yanchor = "bottom",
                     x=0.5,y=1,
                     bgcolor = "transparent"),
         xaxis=list(title=NA,
                    zeroline=FALSE,
                    tickmode = "array",
                    tickvals = unique(as.numeric(sort(as.factor(df$cluster)))),
                    ticktext = unique(sort(as.factor(df$cluster))),
                    gridcolor = "rgba(255,255,255,1)"),
         yaxis=list(title="Val",
                    zeroline=FALSE,
                    gridcolor = "rgba(255,255,255,1)"))


1
投票

我不太熟悉

plotly
包。我不确定这是否符合您的要求。

但这里有一个使用

unite
包中的
tidyr
的解决方法。在与 plotly 一起使用之前创建了 cluster-group
 对。

library(tidyr)

df1 <-  df %>% unite(c('cluster','group'), col = 'clust_grp', sep = "-", remove = F)

plot_ly(df1, x=~clust_grp, y=~point, type='scatter', mode="markers", showlegend=T, color=~group) %>%
    layout(legend=list(orientation="h",xanchor="center",x=0.5,y=1),xaxis=list(title="cluster_group", 
           zeroline=F, categoryorder="array", categoryarray = sort(unique(df1$clust_grp)), showticklabels=T), yaxis=list(title="Val", zeroline=F)) %>%
               plotly::add_trace(error_y=list(array=df1$err), showlegend=F)

© www.soinside.com 2019 - 2024. All rights reserved.