2014-04-08 11 views
11

Sto pianificando una matrice scatterplot utilizzando ggpairs. Sto usando il seguente codice:Come aggiungere una legenda esterna a ggpairs()?

# Load required packages 
require(GGally) 

# Load datasets 
data(state) 
df <- data.frame(state.x77, 
       State = state.name, 
       Abbrev = state.abb, 
       Region = state.region, 
       Division = state.division 
) 
# Create scatterplot matrix 
p <- ggpairs(df, 
      # Columns to include in the matrix 
      columns = c(3,5,6,7), 

      # What to include above diagonal 
      # list(continuous = "points") to mirror 
      # "blank" to turn off 
      upper = "blank", 
      legends=T, 

      # What to include below diagonal 
      lower = list(continuous = "points"), 

      # What to include in the diagonal 
      diag = list(continuous = "density"), 

      # How to label inner plots 
      # internal, none, show 
      axisLabels = "none", 

      # Other aes() parameters 
      colour = "Region", 
      title = "State Scatterplot Matrix" 
) 

# Show the plot 
print(p) 

e ottengo il seguente grafico:

enter image description here

Ora, si può facilmente vedere che sto ottenendo leggende per ogni trama nella matrice. Mi piacerebbe avere SOLO UNA leggenda universale per l'intera trama. Come lo faccio? Qualsiasi aiuto sarebbe molto apprezzato.

+0

Perché questo tagged 'shiny' ??? – jlhoward

+0

Rimosso il tag, grazie per averlo indicato. – Patthebug

risposta

11

sto lavorando su qualcosa di simile, questo è l'approccio che vorrei prendere,

  1. Controlla che le leggende sono impostati su 'VERO' nel ggpairs funzione di chiamata
  2. Ora scorrere i sottotrame nella trama matrice e rimuovere le legende per ognuna di esse e conservare una di esse poiché le densità sono tutte tracciate sulla stessa colonna.

    colIdx <- c(3,5,6,7) 
    
    for (i in 1:length(colIdx)) { 
    
        # Address only the diagonal elements 
        # Get plot out of matrix 
        inner <- getPlot(p, i, i); 
    
        # Add any ggplot2 settings you want (blank grid here) 
        inner <- inner + theme(panel.grid = element_blank()) + 
        theme(axis.text.x = element_blank()) 
    
        # Put it back into the matrix 
        p <- putPlot(p, inner, i, i) 
    
        for (j in 1:length(colIdx)){ 
        if((i==1 & j==1)){ 
    
         # Move legend right 
         inner <- getPlot(p, i, j) 
         inner <- inner + theme(legend.position=c(length(colIdx)-0.25,0.50)) 
         p <- putPlot(p, inner, i, j) 
        } 
        else{ 
    
         # Delete legend 
         inner <- getPlot(p, i, j) 
         inner <- inner + theme(legend.position="none") 
         p <- putPlot(p, inner, i, j) 
        } 
        } 
    } 
    
+0

Grazie, questo funziona perfettamente, realizza esattamente quello che speravo. – Patthebug

7

Eventualmente, qualcuno mostrerà come ciò può essere fatto con ggpairs(...). Mi piacerebbe vederlo anch'io. Fino ad allora, ecco una soluzione che non utilizza ggpairs(...), ma piuttosto semplice vaniglia ggplot con facet.

library(ggplot2) 
library(reshape2) # for melt(...) 
library(plyr)  # for .(...) 
library(data.table) 

xx <- with(df, data.table(id=1:nrow(df), group=Region, df[,c(3,5,6,7)])) 
yy <- melt(xx,id=1:2, variable.name="H", value.name="xval") 
setkey(yy,id,group) 
ww <- yy[,list(V=H,yval=xval),key="id,group"] 
zz <- yy[ww,allow.cartesian=T] 
setkey(zz,H,V,group) 
zz <- zz[,list(id, group, xval, yval, min.x=min(xval),min.y=min(yval), 
       range.x=diff(range(xval)),range.y=diff(range(yval))),by="H,V"] 
d <- zz[H==V,list(x=density(xval)$x, 
        y=min.y+range.y*density(xval)$y/max(density(xval)$y)), 
     by="H,V,group"] 
ggplot(zz)+ 
    geom_point(subset= .(xtfrm(H)<xtfrm(V)), 
      aes(x=xval, y=yval, color=factor(group)), 
      size=3, alpha=0.5)+ 
    geom_line(subset= .(H==V), data=d, aes(x=x, y=y, color=factor(group)))+ 
    facet_grid(V~H, scales="free")+ 
    scale_color_discrete(name="Region")+ 
    labs(x="", y="") 

L'idea di base è quella di melt(...) tua df nel formato corretto per ggplot (xx), fare due copie (yy e ww) ed eseguire un join cartesiano sulla base di id e group (qui , id è solo un numero di riga e group è la variabile Region), per creare zz. Abbiamo bisogno di calcolare e ridimensionare le densità esternamente (nella tabella dati d). Nonostante tutto, funziona ancora più velocemente di ggpairs(...).

+0

grazie per la tua risposta. Possiamo sbarazzarci della matrice triangolare superiore che non sta contribuendo molto? Il motivo dell'utilizzo iniziale di ggpairs per me era solo la visualizzazione di informazioni rilevanti. – Patthebug

+1

No. Non è possibile impostare autonomamente i temi dei facet. – jlhoward