2016-04-06 9 views
1

Ich möchte ein Diagramm erstellen, bei dem der Bereich zwischen den Zeilen basierend auf einem Faktor einer Variablen gefüllt wird. Ich möchte, dass das Polygon rot ist, wenn die Zeile ya > yb und grün ist, wenn yb > ya.Farbvariation mit geom_polygon

xa <- c(1,2,3,4,5,6) 
ya <- c(1,10,15,7,12,3) 
xb <- c(1,2,3,4,5,6) 
yb <- c(5,10,14,12,2,11) 
toyset <- as.data.frame(cbind(xa, ya, xb, yb)) 
toyset$color<-ifelse(toyset$yb>ya,"green","red") 

poly_df <- rbind(setNames(toyset[,c(1,2,5)],c('x','y','color')), 
      setNames(toyset[6:1,3:5],c('x','y','color'))) 

Dies ist gar nicht funktioniert:

ggplot(toyset) + 
geom_line(aes(xa, ya), colour="red") + 
geom_line(aes(xb, yb), colour="green") + 
geom_polygon(data = poly_df,aes(x = x,y = y,fill=poly_df$color)) 

Hier werden die Polygone sind in Ordnung, aber es gibt keine unterschiedlichen Farben (siehe Bild):

ggplot(toyset) + 
geom_line(aes(xa, ya), colour="red") + 
geom_line(aes(xb, yb), colour="green") + 
geom_polygon(data = poly_df,aes(x = x,y = y),fill=poly_df$color) 

plot with no colour variation

+2

Ich denke, Sie müssen die Koordinaten jedes der fünf Polygone zuerst definieren und eine ID und Farbe zu jedem Polygon zuweisen, dann können Sie mit 'geom_polygon (data = poly_df, aes (x = x, y = y, fill = id, color = id)) ' – beetroot

+0

Habe ich das nicht schon beim Erstellen von poly_df getan? – PvGelder

+0

Ich glaube nicht. Sie müssen auch die Punkte einfügen, an denen sich beide Linien schneiden. – beetroot

Antwort

1

Nach dem Beispiel in dieser blog könnten Sie wie folgt vorgehen.

Wir verwenden den anfänglichen Spielzeugdatensatz (leicht angepasst)

x1 <- c(1, 2, 3, 4, 5, 6) 
y1 <- c(1, 10, 15, 7, 12, 3) 
y2 <- c(5, 10, 14, 12, 2, 11) 
toyset <- as.data.frame(cbind(x1, y1, y2)) 

Um die Füllfarbe an jedem Punkt zu ändern, an dem zwei Linien kreuzen, berechnen wir die Schnittpunkte.

toyset$slope1 <- c(NA, with(toyset, diff(y1)/diff(x1))) 
toyset$slope2 <- c(NA, with(toyset, diff(y2)/diff(x1))) 
toyset$intcpt1 <- with(toyset, y1 - slope1 * x1) 
toyset$intcpt2 <- with(toyset, y2 - slope2 * x1) 
toyset$x2 <- with(toyset, (intcpt1 - intcpt2)/(slope2 - slope1)) 
toyset$y3 <- with(toyset, slope1 * x2 + intcpt1) 
toyset <- toyset[, c(-4:-7)] 

Um sicherzustellen, dass Berechnungen korrekt sind, können wir die Position der Schnittpunkte visuell überprüfen:

ggplot(toyset) + geom_line(aes(x1, y1), colour = "red") + 
    geom_line(aes(x1, y2), colour = "darkgreen") + 
    geom_point(aes(x2, y3), colour = "darkblue", size = 3) 

Wie wir geom_ribbon werden verwenden, müssen die Schnittpunkte auch präsentiert werden in der Form, die von geom_ribbon(x, ymin, ymax) erwartet wird - eine einfache Kopie von y3 erreicht dies.

toyset$y4 <- toyset$y3 

Wir führen eine zusätzliche Fehlerprüfung durch und weisen jeden Datenpunkt dem entsprechenden Intervall zu.

toyset[which(toyset$x2 > toyset$x1), c("x2", "y3", "y4")] <- NA 
toyset$segment <- findInterval(toyset$x1, 
           c(min(toyset$x2, na.rm = TRUE), 
            toyset$x2[which(!is.na(toyset$x2))])) 

Für ggplot2 die Lage sein, die Füllfarbe an jeder Kreuzung der Linien zu ändern, braucht es den Start- und Endpunkt jeden farbigen Bereich kennen. Dies bedeutet, dass die mittleren Schnittpunkte dupliziert werden müssen, da sie Teil von zwei benachbarten Bereichen sind, die mit verschiedenen Farben gefüllt sind.

toyset$x3 <- c(tail(toyset$x2, -1), NA) 
toyset$y5 <- c(tail(toyset$y3, -1), NA) 
toyset$y6 <- toyset$y5 

Nun werden die Koordinaten von zwei Zeilen und die Start/Endpunkte Farbflächen müssen in eine data.frame in einem langen Format kombiniert werden.

toyset1 <- toyset[, c(1:3, 7)] 
toyset2 <- toyset[!is.na(toyset$x2), c(4:6, 7)] 
toyset3 <- toyset[!is.na(toyset$x3), c(8:10, 7)] 

names(toyset2) <- names(toyset1) 
names(toyset3) <- names(toyset1) 

combo <- rbind(toyset1, toyset2) 
combo <- rbind(combo, toyset3) 
combo <- combo[is.finite(combo$y1), ] 
combo <- combo[order(combo$x1), ] 

Wir können jetzt die Segmente entsprechend füllen.

ggplot(combo, aes(x1, ymin = y1, ymax = y2))+ 
    geom_ribbon(aes(fill = factor(segment%%2)), alpha = 0.5) + 
    geom_path(aes(y = y1), colour = "red", size = 1) + 
    geom_path(aes(y = y2), colour = "darkgreen", size = 1) + 
    scale_fill_manual(values = c("red", "green")) 

Segments filled

+1

Ah ja, das scheint zu funktionieren! Vielen Dank! Wenn Sie die vollständige Antwort auch hier posten, kann ich sie als beantwortet markieren. Durch das bloße Verlinken des Blogs können die Informationen im Laufe der Zeit verloren gehen. – PvGelder

+0

Sorry, ich bin ziemlich neu in stackoverflow. Ich bin mir nicht sicher, ob es eine einfachere Lösung für dieses Problem gibt, aber ich hoffe meine volle Antwort hilft! – rhole

Verwandte Themen