2016-09-28 3 views
4

Ich versuche ein Streudiagramm mit geom_point zu erzeugen, bei dem die Punkte von einem geglätteten Polygon mit geom_polygon umschrieben werden.Eine Legende für geom_polygon hinzufügen

Hier ist meine Punktdaten:.

set.seed(1) 
df <- data.frame(x=c(rnorm(30,-0.1,0.1),rnorm(30,0,0.1),rnorm(30,0.1,0.1)),y=c(rnorm(30,-1,0.1),rnorm(30,0,0.1),rnorm(30,1,0.1)),val=rnorm(90),cluster=c(rep(1,30),rep(2,30),rep(3,30)),stringsAsFactors=F) 

ich jeden Punkt Farbe das ein Intervall nach, dass df$val in ist hier die Intervalldaten:

intervals.df <- data.frame(interval=c("(-3,-2]","(-2,-0.999]","(-0.999,0]","(0,1.96]","(1.96,3.91]","(3.91,5.87]","not expressed"), 
          start=c(-3,-2,-0.999,0,1.96,3.91,NA),end=c(-2,-0.999,0,1.96,3.91,5.87,NA), 
          col=c("#2f3b61","#436CE8","#E0E0FF","#7d4343","#C74747","#EBCCD6","#D3D3D3"),stringsAsFactors=F) 

Farben und Intervalle zu den Punkten zuordnen:

df <- cbind(df,do.call(rbind,lapply(df$val,function(x){ 
    if(is.na(x)){ 
    return(data.frame(col=intervals.df$col[nrow(intervals.df)],interval=intervals.df$interval[nrow(intervals.df)],stringsAsFactors=F)) 
    } else{ 
    idx <- which(intervals.df$start <= x & intervals.df$end >= x) 
    return(data.frame(col=intervals.df$col[idx],interval=intervals.df$interval[idx],stringsAsFactors=F)) 
    } 
}))) 

Vorbereiten der Farben für die leged, die ea zeigen wird ch-Intervall:

df$interval <- factor(df$interval,levels=intervals.df$interval) 
colors <- intervals.df$col 
names(colors) <- intervals.df$interval 

Hier ist, wo ich die geglätteten Polygonen aufgebaut (eine Funktion, mit freundlicher Genehmigung von diesen link verwenden):

clusters <- sort(unique(df$cluster)) 
cluster.cols <- c("#ff00ff","#088163","#ccbfa5") 


splinePolygon <- function(xy,vertices,k=3, ...) 
{ 
    # Assert: xy is an n by 2 matrix with n >= k. 
    # Wrap k vertices around each end. 
    n <- dim(xy)[1] 
    if (k >= 1) { 
    data <- rbind(xy[(n-k+1):n,], xy, xy[1:k, ]) 
    } else { 
    data <- xy 
    } 
    # Spline the x and y coordinates. 
    data.spline <- spline(1:(n+2*k), data[,1], n=vertices, ...) 
    x <- data.spline$x 
    x1 <- data.spline$y 
    x2 <- spline(1:(n+2*k), data[,2], n=vertices, ...)$y 
    # Retain only the middle part. 
    cbind(x1, x2)[k < x & x <= n+k, ] 
} 

library(data.table) 
hulls.df <- do.call(rbind,lapply(1:length(clusters),function(l){ 
    dt <- data.table(df[which(df$cluster==clusters[l]),]) 
    hull <- dt[, .SD[chull(x,y)]] 
    spline.hull <- splinePolygon(cbind(hull$x,hull$y),100) 
    return(data.frame(x=spline.hull[,1],y=spline.hull[,2],val=NA,cluster=clusters[l],col=cluster.cols[l],interval=NA,stringsAsFactors=F)) 
})) 
hulls.df$cluster <- factor(hulls.df$cluster,levels=clusters) 

Und hier ist mein ggplot Befehl:

library(ggplot2) 

p <- ggplot(df,aes(x=x,y=y,colour=interval))+geom_point(cex=2,shape=1,stroke=1)+labs(x="X", y="Y")+theme_bw()+theme(legend.key=element_blank(),panel.border=element_blank(),strip.background=element_blank())+scale_color_manual(drop=FALSE,values=colors,name="DE") 
p <- p+geom_polygon(data=hulls.df,aes(x=x,y=y,group=cluster),color=hulls.df$col,fill=NA) 

, die produziert:

enter image description here

Meine Frage ist, wie füge ich eine Legende für das Polygon unter der Legende für die Punkte hinzu? Ich will es zu einer Legende mit 3 Linien, die entsprechend der Clusterfarben und der entsprechenden Clusternummer neben jeder Zeile farbig sind?

Antwort

2

Etwas andere Ausgabe, nur die letzte Zeile des Codes zu ändern, kann es Ihre Aufgabe lösen:

p+geom_polygon(data=hulls.df,aes(x=x,y=y,group=cluster, fill=cluster),alpha=0.1) 

enter image description here

+0

Wenn Sie das Polygon vor die Punkte setzen, können Sie mit einem höheren Alpha kommen. – Axeman

3

Sagen Sie, Sie wollen eine legend von the_factor hinzuzufügen. Meine Grundidee ist,

(1) setzen the_factor in Mapping mit unbenutzten aes Argumente; mit guides(xx = guide_legend(override.aes = list()))

In Ihrem Fall aes(xx = the_factor)
(2), wenn (1) etwas wirkt, die Wirkung löschen, indem scale_xx_manual() mit
(3) durch die legend ändern, aes(fill) und aes(alpha) sind ungenutzt. Ersteres ist besser, weil es keinen Effekt hat. Also habe ich aes(fill=as.factor(cluster)) verwendet.

p <- ggplot(df,aes(x=x,y=y,colour=interval, fill=as.factor(cluster))) + # add aes(fill=...) 
    geom_point(cex=2, shape=1, stroke=1) + 
    labs(x="X", y="Y",fill="cluster") +   # add fill="cluster" 
    theme_bw() + theme(legend.key=element_blank(),panel.border=element_blank(),strip.background=element_blank()) + scale_color_manual(drop=FALSE,values=colors,name="DE") + 
    guides(fill = guide_legend(override.aes = list(colour = cluster.cols, pch=0))) # add 

p <- p+geom_polygon(data=hulls.df,aes(x=x,y=y,group=cluster), color=hulls.df$col,fill=NA) 


Natürlich können Sie das gleiche Diagramm machen, indem aes(alpha = the_factor)) verwenden. Weil es Einfluss hat, müssen Sie es mit scale_alpha_manual() steuern.

g <- ggplot(df, aes(x=x,y=y,colour=interval)) + 
    geom_point(cex=2, shape=1, stroke=1, aes(alpha=as.factor(cluster))) + # add aes(alpha) 
    labs(x="X", y="Y",alpha="cluster") +   # add alpha="cluster" 
    theme_bw() + theme(legend.key=element_blank(),panel.border=element_blank(),strip.background=element_blank()) + scale_color_manual(drop=FALSE,values=colors,name="DE") + 
    scale_alpha_manual(values=c(1,1,1)) +   # add 
    guides(alpha = guide_legend(override.aes = list(colour = cluster.cols, pch=0))) # add 

g <- p+geom_polygon(data=hulls.df,aes(x=x,y=y,group=cluster), color=hulls.df$col,fill=NA) 

enter image description here

2

Was Sie fordern ist zwei Farbskalen.Mein Verständnis ist, dass dies nicht möglich ist. Sie können jedoch den Eindruck erwecken, zwei Farbskalen mit einer kleinen Zahl von cheat zu haben und die gefüllten Symbole (Formen 21 bis 25) zu verwenden.

p <- ggplot(df, aes(x = x, y = y, fill = interval)) + 
    geom_point(cex = 2, shape = 21, stroke = 1, colour = NA)+ 
    labs(x = "X", y = "Y") + 
    theme_bw() + 
    theme(legend.key = element_blank(), panel.border = element_blank(), strip.background = element_blank()) + 
    scale_fill_manual(drop=FALSE, values=colors, name="DE") + 
    geom_polygon(data = hulls.df, aes(x = x, y = y, colour = cluster), fill = NA) + 
    scale_colour_manual(values = cluster.cols) 
p 

Alternativ verwenden Sie ein gefülltes Polygon mit einem niedrigen alpha

p <- ggplot(df,aes(x=x,y=y,colour=interval))+ 
    geom_point(cex=2,shape=1,stroke=1)+ 
    labs(x="X", y="Y")+ 
    theme_bw() + 
theme(legend.key = element_blank(),panel.border=element_blank(), strip.background=element_blank()) + 
    scale_color_manual(drop=FALSE,values=colors,name="DE", guide = guide_legend(override.aes = list(fill = NA))) + 
    geom_polygon(data=hulls.df,aes(x=x,y=y,group=cluster, fill = cluster), alpha = 0.2, show.legend = TRUE) + 
     scale_fill_manual(values = cluster.cols) 
    p 

Aber dies könnte die Punkt Farben schwer zu sehen, machen.

Verwandte Themen