2016-12-14 5 views
1

Ich möchte Daten für ein lineares Modell in einem Hauptdiagramm und ein Diagramm der Effekte (Gesamtstrukturdiagramm) als Unterdiagramm mit arrangeGrob plotten.Positionierung von grobs

Hier sind die Daten:

set.seed(1) 
main.df <- data.frame(sample=c(paste("E.plus.A.plus",1:3,sep="_"),paste("E.minus.A.plus",1:3,sep="_"),paste("E.plus.A.minus",1:3,sep="_"),paste("E.minus.A.minus",1:3,sep="_")), 
         replicate=rep(1:3,4),cpm=c(rnorm(12)), 
         factor.level=factor(c(rep("E.plus.A.plus",3),rep("E.minus.A.plus",3),rep("E.plus.A.minus",3),rep("E.minus.A.minus",3)), 
            levels=c("E.plus.A.plus","E.minus.A.plus","E.plus.A.minus","E.minus.A.minus"))) 

effects.df <- data.frame(factor.level=c("E.plus.A.plus-E.minus.A.plus","E.plus.A.plus-E.plus.A.minus","E.plus.A.plus-E.minus.A.minus", 
             "E.minus.A.plus-E.plus.A.minus","E.minus.A.plus-E.minus.A.minus","E.plus.A.minus-E.minus.A.minus"), 
         effect=rnorm(6),effect.df=runif(6,0,0.5),p.value=runif(6,0,1),y=1:6+0.2) 
effects.df$effect.high <- effects.df$effect+effects.df$effect.df 
effects.df$effect.low <- effects.df$effect-effects.df$effect.df 
effects.df$factor.level <- factor(effects.df$factor.level,levels=effects.df$factor.level) 

Die ggplots:

require(ggplot2) 
require(grid) 
require(gridExtra) 
main.plot <- ggplot(main.df,aes(x=replicate,y=cpm,color=factor.level))+geom_point(size=3)+ 
    facet_wrap(~factor.level,ncol=length(levels(main.df$factor.level)))+ 
    labs(x="replicate",y="cpm")+scale_x_continuous(breaks=unique(main.df$replicate))+theme_bw()+ 
    theme(legend.key=element_blank(),panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=8),plot.title=element_text(size=9,hjust=0.5)) 

Welche ist: enter image description here

sub.plot <- ggplot(effects.df,aes(x=effect,y=factor.level,color=factor.level))+geom_point(size=2.5,shape=19)+geom_errorbarh(aes(xmax=effect.high,xmin=effect.low),height=0.1)+ 
    geom_vline(xintercept=0,linetype="longdash",colour="black",size=0.25)+theme_bw()+theme(legend.key=element_blank(),panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=7),axis.text=element_text(size=7),legend.text=element_text(size=7),legend.title=element_text(size=7))+ 
    geom_text(aes(x=effects.df$effect,y=effects.df$y,label=format(signif(effects.df$p.value,2),scientific=T)),size=2.5) 

Und ist: enter image description here

Und hier ist, wie ich versuche, sie zu einem einzigen Grundstück zu kombinieren:

if(!is.null(dev.list())) dev.off() 
blank <- grid.rect(gp = gpar(col = "white")) 
sub.plot.grob <- arrangeGrob(blank,sub.plot,ncol=1) 
combined.plot <- arrangeGrob(main.plot,sub.plot,ncol=2,widths=c(1,1)) 
grid.arrange(combined.plot) 

die gibt: enter image description here

Wie stelle ich die Position und die Abmessungen, so dass sub.plot kleiner ist (alle Schichten, zum Beispiel, Text wird proportional reduziert) und befindet sich unterhalb der Legende main.plot?

+0

Nur eine kurze Notiz. Warum brauchst du die Legende überhaupt? Ihre Variablen scheinen durch verschiedene Facetten oder Positionen auf der y-Achse gut repräsentiert zu sein. Übrigens, hast du [das] gesehen (http: // stackoverflow.com/questions/36198451/specify-widthes-and-heights-of-plots-mit-grid-arranges) und [this] (https://cran.r-project.org/web/packages/gridExtra/vignettes/arrangeGrob .html)? –

Antwort

2

Ich empfehle das Paket cowplot für diese Art von Aufgabe. Hier baue ich drei verschachtelte Sets (das Haupt-Plot links, dann die beiden Legenden zusammen oben rechts, dann das Sub-Plot unten rechts). Beachten Sie die wunderbare get_legend Funktion, die das Ziehen der Legenden unglaublich einfach macht.

plot_grid(
    main.plot + theme(legend.position = "none") 
    , plot_grid(
    plot_grid(
     get_legend(main.plot) 
     , get_legend(sub.plot) 
     , nrow = 1 
    ) 
    , sub.plot + theme(legend.position = "none") 
    , nrow = 2 
) 
    , nrow = 1 
) 

gibt:

enter image description here

Offensichtlich würde ich empfehlen, eine (oder beide) der Farbpaletten zu ändern, aber das sollte, was Sie wollen.

Wenn Sie wirklich die Legende mit dem sub.plot möchten, können Sie anstelle der anderen Legende die get_legend überspringen.

Sie können auch die Breite/Höhe der Sätze mit rel_widths und rel_heights anpassen, wenn Sie etwas anderes als die geraden Größen möchten.

Als zusätzliche Anmerkung setzt cowplot sein eigenes Standardthema auf laden. Ich gehe im Allgemeinen zu dem zurück, was ich mag, indem ich direkt nach dem Laden theme_set(theme_minimal()) läuft.

1

hier eine grid.arrange Lösung,

grid.arrange(grobs = replicate(4, ggplot(), simplify = FALSE), 
      layout_matrix = cbind(c(1,1), c(3,2), c(4, 2)), 
      widths = c(2,1,1)) 

enter image description here

mit den Bits und Stücke,

get_legend <- function(p) { 
    g <- ggplotGrob(p) 
    id <- grep("guide", g$layout$name) 
    g$grobs[[id]] 
} 

leg1 <- get_legend(main.plot); leg2 <- get_legend(sub.plot) 
gl <- list(main.plot + theme(legend.position = "none"), 
      sub.plot + theme(legend.position = "none"), leg1, leg2) 

grid.arrange(grobs = gl, 
      layout_matrix = cbind(c(1,1), c(3,2), c(4, 2)), 
      widths = c(2,1,1)) 

enter image description here