首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为geom_polygon添加图例

为geom_polygon添加图例
EN

Stack Overflow用户
提问于 2016-09-28 14:14:27
回答 3查看 3.3K关注 0票数 4

我正在尝试用geom_polygongeom_point绘制散点图,其中的点被一个平滑的多边形包围。

以下是我的点数:

代码语言:javascript
复制
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)

我根据df$val所在的区间对每个点进行着色。以下是间隔数据:

代码语言:javascript
复制
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)

为点指定颜色和间隔:

代码语言:javascript
复制
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))
  }
})))

为显示每个间隔的图例准备颜色:

代码语言:javascript
复制
df$interval <- factor(df$interval,levels=intervals.df$interval)
colors <- intervals.df$col
names(colors) <- intervals.df$interval

这里是我构造平滑多边形的地方(使用此link提供的函数):

代码语言:javascript
复制
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)

下面是我的ggplot命令:

代码语言:javascript
复制
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)

这会产生:

我的问题是如何在点的图例下添加多边形的图例?我想要一个图例与3行颜色根据簇的颜色和相应的簇号旁边每一行?

EN

回答 3

Stack Overflow用户

发布于 2016-09-28 15:08:13

输出稍有不同,只需更改代码的最后一行,就可以解决您的问题:

代码语言:javascript
复制
p+geom_polygon(data=hulls.df,aes(x=x,y=y,group=cluster, fill=cluster),alpha=0.1)

票数 3
EN

Stack Overflow用户

发布于 2016-09-28 15:53:58

比方说,您想添加一个the_factorlegend。我的基本想法是,

(1)使用未使用的aes参数将the_factor放入映射;aes(xx = the_factor)

(2)如果(1)有影响,使用scale_xx_manual()删除效果

(3)使用guides(xx = guide_legend(override.aes = list()))修改legend

在您的示例中,未使用aes(fill)aes(alpha)。前者更好,因为没有效果。所以我使用了aes(fill=as.factor(cluster))

代码语言:javascript
复制
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)

当然,您也可以使用aes(alpha = the_factor))制作相同的图形。因为它有影响,所以你需要使用scale_alpha_manual()来控制它。

代码语言:javascript
复制
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)

票数 3
EN

Stack Overflow用户

发布于 2016-09-28 16:08:51

你要的是两个色标。我的理解是这是不可能的。但你可以给人一种有两个色标的印象,使用一点cheat并使用填充的符号(形状21到25)。

代码语言:javascript
复制
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

或者,使用具有低alpha的填充多边形

代码语言:javascript
复制
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

但这可能会使点颜色很难看清。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39739327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档