2017-03-01 1 views
2

ggplot2를 사용하여 산점도 오버레이로 그룹화 된 상자 그림을 만듭니다. 각 scatterplot datapoint 해당하는 그룹화 된 boxplot 함께 그룹화하고 싶습니다.ggplot2를 사용하여 R에 그룹화 된 산점도를 R로 그룹화

그러나 산점도 점을 다른 기호로도 사용하고 싶습니다. 내 산점도를 그룹화 된 박스 플롯과 그룹화하거나 산란 점을 다른 심볼로 가져올 수있는 것 같지만 둘 다 동시에는 아닙니다. 아래는 몇 가지 예제 코드입니다.

library(scales) 
library(ggplot2) 

# Generates Data frame to plot 
Gene <- c(rep("GeneA",24),rep("GeneB",24),rep("GeneC",24),rep("GeneD",24),rep("GeneE",24)) 
Clone <- c(rep(c("D1","D2","D3","D4","D5","D6"),20)) 
variable <- c(rep(c(rep("Day10",6),rep("Day20",6),rep("Day30",6),rep("Day40",6)),5)) 
value <- c(rnorm(24, mean = 0.5, sd = 0.5),rnorm(24, mean = 10, sd = 8),rnorm(24, mean = 1000, sd = 900), 
      rnorm(24, mean = 25000, sd = 9000), rnorm(24, mean = 8000, sd = 3000)) 
    value <- sqrt(value*value) 
     Tdata <- cbind(Gene, Clone, variable) 
     Tdata <- data.frame(Tdata) 
      Tdata <- cbind(Tdata,value) 

# Creates the Plot of All Data 
# The below code groups the data exactly how I'd like but the scatter plot points are all the same shape 
# and I'd like them to each have different shapes.       
ln_clr <- "black" 
bk_clr <- "white" 
point_shapes <- c(0,15,1,16,2,17) 
blue_cols <- c("#EFF2FB","#81BEF7","#0174DF","#0000FF","#0404B4") 

lp1 <- ggplot(Tdata, aes(x=variable, y=value, fill=Gene)) + 
    stat_boxplot(geom ='errorbar', position = position_dodge(width = .83), width = 0.25, 
       size = 0.7, coef = 4) + 
    geom_boxplot(coef=1, outlier.shape = NA, position = position_dodge(width = .83), lwd = 0.3, 
        alpha = 1, colour = ln_clr) + 
    geom_point(position = position_jitterdodge(dodge.width = 0.83), size = 1.8, alpha = 0.7, 
       pch=15) 


lp1 + scale_fill_manual(values = blue_cols) + labs(y = "Fold Change") + 
    expand_limits(y=c(0.01,10^5)) + 
    scale_y_log10(expand = c(0, 0), breaks = c(0.01,1,100,10000,100000), 
        labels = trans_format("log10", math_format(10^.x))) 

ggsave("Scatter Grouped-Wrong Symbols.png") 

#************************************************************************************************************************************* 
# The below code doesn't group the scatterplot data how I'd like but the points each have different shapes 
lp2 <- ggplot(Tdata, aes(x=variable, y=value, fill=Gene)) + 
    stat_boxplot(geom ='errorbar', position = position_dodge(width = .83), width = 0.25, 
       size = 0.7, coef = 4) + 
    geom_boxplot(coef=1, outlier.shape = NA, position = position_dodge(width = .83), lwd = 0.3, 
        alpha = 1, colour = ln_clr) + 
    geom_point(position = position_jitterdodge(dodge.width = 0.83), size = 1.8, alpha = 0.7, 
       aes(shape=Clone)) 


lp2 + scale_fill_manual(values = blue_cols) + labs(y = "Fold Change") + 
    expand_limits(y=c(0.01,10^5)) + 
    scale_y_log10(expand = c(0, 0), breaks = c(0.01,1,100,10000,100000), 
        labels = trans_format("log10", math_format(10^.x))) 

ggsave("Scatter Ungrouped-Right Symbols.png") 

누구나 의견을 보내 주시면 감사하겠습니다.

shape 심미적 인 요구가 아니라 ggplot의 주요 통화에 비해, geom_point 내부에, 당신 나단

답변

5

이 상자 그림을 표시 할 수 부탁드립니다. 그 이유는 shape 미학이 기본 ggplot 호출에있을 때 geom_boxplot을 포함한 모든 기하 구조에 적용되기 때문입니다. 그러나 shape=Clone 미적을 적용하면 geom_boxplotClone의 각 레벨에 대해 별도의 상자 그림을 만듭니다. variableClone의 각 조합에 대해 하나의 데이터 행만 있기 때문에 boxplot이 생성되지 않습니다.

shape 미학적 인 영향이 geom_boxplot 인 것은 내게 반 직관으로 보일 수 있지만 어쩌면 내가 알지 못하는 이유가있을 수 있습니다. 어쨌든 shape 미학을 geom_point으로 옮기면 shape의 미학만을 geom_point에 적용하여 문제를 해결할 수 있습니다.

그런 다음 올바른 상자 그림으로 포인트를 표시하려면 groupGene이 필요합니다. X

enter image description here

ggplot(Tdata, aes(x=variable, y=value, fill=Gene)) + 
    stat_boxplot(geom ='errorbar', width=0.25, size=0.7, coef=4, position=position_dodge(0.85)) + 
    geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3, alpha=1, colour=ln_clr, position=position_dodge(0.85)) + 
    geom_point(position=position_jitterdodge(dodge.width=0.85), size=1.8, alpha=0.7, 
      aes(shape=Clone, group=Gene)) + 
    scale_fill_manual(values=blue_cols) + labs(y="Fold Change") + 
    expand_limits(y=c(0.01,10^5)) + 
    scale_y_log10(expand=c(0, 0), breaks=10^(-2:5), 
       labels=trans_format("log10", math_format(10^.x))) + 
    theme_classic() 
내가 줄거리는 Gene과에 대한 패 시팅 (faceting)를 사용하는 경우 더 쉽게 이해할 수있을 거라고 생각 : 나는 또한 (가 여전히 매우 바쁜 있지만) 쉽게 줄거리를 볼 수 있도록 theme_classic 추가 variable에 대한 축 X 축에 시간을 두는 것은 직관적 인 것처럼 보이지만 패싯을 사용하면 점에 대한 색상 미적 감각을 확보 할 수 있습니다. 6 개의 다른 클론을 사용하면 포인트 마커를 구별하는 것은 여전히 ​​어렵지만 (이전 버전보다 나에게 더 깨끗해 보인다)

library(dplyr) 

ggplot(Tdata %>% mutate(Gene=gsub("Gene","Gene ", Gene)), 
     aes(x=gsub("Day","",variable), y=value)) + 
    stat_boxplot(geom='errorbar', width=0.25, size=0.7, coef=4) + 
    geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3, alpha=1, colour=ln_clr, width=0.5) + 
    geom_point(aes(fill=Clone), position=position_jitter(0.2), size=1.5, alpha=0.7, shape=21) + 
    theme_classic() + 
    facet_grid(. ~ Gene) + 
    labs(y = "Fold Change", x="Day") + 
    expand_limits(y=c(0.01,10^5)) + 
    scale_y_log10(expand=c(0, 0), breaks=10^(-2:5), 
       labels=trans_format("log10", math_format(10^.x))) 

enter image description here

당신이 정말로 포인트를 유지할 필요가 있다면, 어쩌면 일부 수동 닷징과 상자 그림과 포인트를 분리하는 더 나은 것 :

set.seed(10) 
ggplot(Tdata %>% mutate(Day=as.numeric(substr(variable,4,5)), 
         Gene = gsub("Gene","Gene ", Gene)), 
     aes(x=Day - 2, y=value, group=Day)) + 
    stat_boxplot(geom ='errorbar', width=0.5, size=0.5, coef=4) + 
    geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3, alpha=1, width=4) + 
    geom_point(aes(x=Day + 2, fill=Clone), size=1.5, alpha=0.7, shape=21, 
      position=position_jitter(width=1, height=0)) + 
    theme_classic() + 
    facet_grid(. ~ Gene) + 
    labs(y="Fold Change", x="Day") + 
    expand_limits(y=c(0.01,10^5)) + 
    scale_y_log10(expand=c(0, 0), breaks=10^(-2:5), 
       labels=trans_format("log10", math_format(10^.x))) 

enter image description here

하나 더 많은 것 : 나중에 참조 할 수 있도록 데이터 생성 코드를 간소화 할 수 있습니다.

Gene = rep(paste0("Gene",LETTERS[1:5]), each=24) 
Clone = rep(paste0("D",1:6), 20) 
variable = rep(rep(paste0("Day", seq(10,40,10)), each=6), 5) 
value = rnorm(24*5, mean=rep(c(0.5,10,1000,25000,8000), each=24), 
       sd=rep(c(0.5,8,900,9000,3000), each=24)) 

Tdata = data.frame(Gene, Clone, variable, value) 
+1

아마도 내가 본 것 중 가장 훌륭하고 철저하고 잘 표현 된 대답 일 것입니다. 도와 주셔서 정말 감사합니다. 당신이 쓴 모든 것은 엄청난 도움이되었습니다.만약 내가 얼마나 환상적인지에 대한 표결보다 더 많은 크레딧을 줄 수 있다면. 고맙습니다. – Nathan

+0

감사합니다, Nathan! 정말 친절 하구나. – eipi10