2016-07-23 7 views
2

Ich sammelte die Daten aus einer Reihe von Online-Foren und wollte plotten, mit ggplot und Facetten (eine Facette pro Forum), die Matrix, wie oft Benutzer A auf Benutzer antwortete B.Plot mehrere Matrizen in Facetten mit verschiedenen XY-Achse

Hier ist der Code ein Spielzeug Beispiel zu laden:

library(ggplot2) 
library(dplyr) 

df.edges <- data.frame(from = c('forum1_user1', 'forum1_user1', 
           'forum1_user2', 'forum1_user2', 
           'forum2_user1', 'forum2_user1', 
           'forum2_user2', 'forum2_user2', 
           'forum3_user1', 'forum3_user1', 
           'forum3_user2', 'forum3_user2'), 
         to = c('forum1_user1', 'forum1_user2', 
           'forum1_user1', 'forum1_user2', 
           'forum2_user1', 'forum2_user2', 
           'forum2_user1', 'forum2_user2', 
           'forum3_user1', 'forum3_user2', 
           'forum3_user1', 'forum3_user2'), 
         weight = 1:12, 
         timestamp = 1:12, 
         subforum = c('forum1', 'forum1', 'forum1', 'forum1', 
            'forum2', 'forum2', 'forum2', 'forum2', 
            'forum3', 'forum3', 'forum3', 'forum3')) 

ich das versuchen:

# Sort for later use in scale_discrete 
df.edges <- df.edges %>% arrange(timestamp) 


gg <- ggplot(df.edges, aes(x = from, y = to, fill = weight)) + 
    geom_raster() + coord_fixed() + 
    facet_grid(. ~subforum, scales='fixed') + 
    scale_x_discrete("from", aes(limits = from))+ 
    scale_y_discrete("to", aes(limits = from)) + 
    theme_bw() + 
    theme(axis.line  = element_blank(), 
     axis.text.x  = element_text(angle = 90, hjust=1, size=8), 
     axis.text.y  = element_text(hjust=1, size=10), 
     axis.ticks  = element_blank(), 
     strip.background = element_rect(fill = 'white'), 
     aspect.ratio = 1) + 
    ggtitle("Matrix of interactions") + xlab('from') + ylab('to') 
print(gg) 

das gibt dies:

enter image description here

Und wenn ich die Facette Skala gesetzt scale='free':

enter image description here

Allerdings möchte ich jede Facette nur die Benutzer in diesem Forum gehören, zeigen. Die Matrizen sollten vollständig mit jeweils 4 Zellen gefüllt sein.

Irgendeine Idee?

+0

Ich glaube nicht, dass Sie das mit 'facet_grid' machen können, versuchen Sie' facet_wrap' zu verwenden oder optimieren Sie Ihre Daten..'df.edges [c ("from", "to")] <- lapply (df.edges [c ("von", "zu")], gsub, pattern = "forum \\ d + _", ersatz = "") ' – user20650

Antwort

3

Sie könnten ein separates Grundstück für jede Ebene der subforum erstellen und sie dann legen zusammen grid.arrange mit aus:

library(gridExtra) 
library(grid) 

Zuerst die einzelnen Parzellen und speichern Sie in einer Liste erstellen. Wir fügen scale_fill_continuous(limits=range(df.edges$weight)) eine konsistente fill-Gradienten über die drei Grundstücke zu gewährleisten:

pl = lapply(split(df.edges, df.edges$subforum), function(df) { 
    ggplot(df, aes(x = from, y = to, fill = weight)) + 
     geom_raster() + coord_fixed() + 
     facet_grid(. ~subforum, scales='fixed') + 
     scale_x_discrete("from", aes(limits = from))+ 
     scale_y_discrete("to", aes(limits = from)) + 
     scale_fill_continuous(limits=range(df.edges$weight)) + 
     theme_bw() + 
     theme(axis.line  = element_blank(), 
      axis.text.x  = element_text(angle = 90, hjust=1, size=8), 
      axis.text.y  = element_text(hjust=1, size=10), 
      axis.ticks  = element_blank(), 
      strip.background = element_rect(fill = 'white'), 
      aspect.ratio = 1) + 
     xlab('from') + ylab('to') 
    }) 

die Legende Extract, da wir nur eine Legende wollen, anstatt eine separate Legende für jede Parzelle:

# Function to extract legend 
#https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs 
g_legend<-function(a.gplot){ 
    tmp <- ggplot_gtable(ggplot_build(a.gplot)) 
    leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") 
    legend <- tmp$grobs[[leg]] 
    return(legend) } 

# Extract legend as a grob 
leg = g_legend(pl[[1]]) 

Ordnen Sie die Plots mit Legende und Titel:

grid.arrange(
    textGrob("Matrix of Interactions"), 
    arrangeGrob(
    arrangeGrob(grobs=lapply(pl, function(x) x + guides(fill=FALSE)), ncol=3), 
    leg, ncol=2, widths=c(10,1) 
), 
    heights=c(1,20) 
) 

enter image description here

+0

Danke eipi10, das funktioniert! Aber nur für den Datensatz, wenn Sie möchten, dass Sie die Benutzerkennung (es ist nicht mein Fall, weil ich tausend) in der Achse und ihre Benutzernamen haben unterschiedliche Längen, jede Matrix hat eine andere Größe. – alberto

+1

Sie können sicherstellen, dass der Plotbereich in jedem Plot die gleiche Größe hat, indem Sie die 'plot_grid'-Funktion aus dem' cookplot'-Pacakge verwenden. Siehe auch [diese SO-Antwort] (http://stackoverflow.com/a/35304121/496488). – eipi10