本文介绍了叠加ggplot根据多余的因素将多边形边界的图块分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我有一个x和y位置的数据框和两个因子列blocknr和cat: dput(testData)$ bL结构(列表(xpos = c(2L,8L,5L,8L,1L,4L,5L,1L,8L,4L, 3L,2L,6L,5L,1L,7L,3L,4L ,3L,7L,1L,6L,7L,7L,2L,5L, 3L,4L,6L,7L,1L,5L,1L,6L,4L,5L,3L,6L,4L,8L, ,3L, 4L,6L,7L,3L,2L,6L,4L,2L,1L,7L,4L,8L,2L,3L,2L,5L, 8L,2L,8L,3L 3L,5L,6L,7L,1L,5L,6L,4L,2L,6L,7L,1L, 5L,7L,2L),ypos = c(1L,2L,8L,1L,6L, 7L,1L,4L,6L,1L, 2L,3L,4L,5L,7L,8L,10L,2L,6L,9L,1L,2L,10L,4L,5L, 3L,5L,9L,3L,9L,10L,3L,7L,8L,2L,5L,6L,3L,4L, 10L,1L,4L,10L,2L,8L,9L,3L, 8L,5L,7L,10L,3L,4L, 7L,2L,4L,5L,6L,7L,9L,4L,7L,8L,1L,2L,9L,5L,9L,10L, (1L,3L,2L,3L,1L,2L, 2L,1L,3L,2L,1L,1L,3L,2L) ,1L,3L,2L,2L,1L,3L,1L,2L, 3L,3L,1L,2L,1L,2L,3L,3L,1L,2 L,1L,3L,2L,2L,1L,3L, 2L,3L,1L,1L,2L,3L,3L,2L,1L,3L,2L,1L, 1L,2L,1L,2L,3L,1L,3L,2L,1L,2L,3L,3L,1L,2L,3L,2L, 1L,2L,3L,1L,2L, (2L,2L,2L,2L, 2L,2L,2L,2L,2L,3L,3L,3L,3L,3L,3L,3L,3L,1L) 1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L, ,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,1L, 1L,1L,1L,1L,1L,1L, 1L,1L,1L,1L,1L, 1L,1L,1L,1L,1L,1L,2L,2L,2L),标签= c(A,B C)),.Names = c(xpos,ypos,blocknr,cat),row.names = c(NA, -77L),class =data.frame) 我制作了以下ggplot代码进行2D概述: ggplot(data = testData,aes(x = xpos,y = ypos))+ geom_tile(aes(fill = cat),color =white)+ scale_fill_manual(values = c('A'='#F8766D','C'='#8ABF5 4','B'='#C1DDA5'))+ geom_text(aes(x = xpos,y = ypos,label = blocknr),size = 3)+ coord_cartesian(ylim = c 0.5,ymax + 0.5))+ coord_cartesian(xlim = c(0.5,xmax + 0.5))+ scale_x_continuous(breaks = seq(1,xmax,1))+ scale_y_continuous break = seq(1,ymax,1))+ #geom_polygon(aes(group = blocknr))+ theme(axis.line = element_line(color =white), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), panel.background = element_blank()) 产生以下结果: 现在我想要突出显示每组阻塞者以下: 我玩过 geom_polygon , geo m_path ,但我不能完全找到一种方法来做到这一点。是否有一种通用的方法可以在 ggplot 中实现此功能,而无需构建算法来计算每行的位置,并将这些行添加为 geom_segment ymax xmax $ bm m [as.matrix(testData [,2:1])] 在这里,我们基本上是取所有的行/列分配数据并创建一个矩阵,但我们会与块号码。现在,我们将通过查找块数量的变化来扫描我们需要添加墙的位置,因为我们分别遍历每行和每列。 has.breaks< -function(x)ncol(x)== 2& (x)> 0 hw cbind(y = i,x = which(diff(c(0,x,0))!= 0)),1:nrow(m),split(m,1:nrow(m))))) vw< -do.call(rbind.data.frame,Filter(has.breaks,Map(函数(i,x)) cbind(x = i,y = which(diff(c(0,x,0)) !)= 1):ncol(m),as.data.frame(m)))) ggplot(data = testData)您可以添加对geom_segments的调用以将水平和垂直墙添加到图中。 ,aes(x = xpos,y = ypos))+ geom_tile(aes(fill = cat),color =white)+ scale_fill_manual(values = c('A'='#F8766D ','C'='#8ABF54','B'='#C1DDA5'))+ geom_text(aes(x = xpos,y = ypos,label = blocknr),size = 3)+ geom_segment(data = hw,aes(x = x-.5,xend = x-.5,y = y-.5,yend = y + .5))+ geom_segment(data = vw,aes (x = x-0.5,xend = x + 0.5,y = y-0.5,yend = y-0.5))+ coord_cartesian(ylim = c(0.4,ymax + 0.6))+ coord_cartesian(xlim = c(0.4,xmax + 0.6))+ scale_x_co ntinuous(breaks = seq(1,xmax,1))+ scale_y_continuous(breaks = seq(1,ymax,1))+ theme(axis.line = element_line(color =white)) , panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), panel.background = element_blank ()) 给出 I have a data frame with x and y positions and two factor columns blocknr and cat:dput(testData)structure(list(xpos = c(2L, 8L, 5L, 8L, 1L, 4L, 5L, 1L, 8L, 4L, 3L, 2L, 6L, 5L, 1L, 7L, 3L, 4L, 3L, 7L, 1L, 6L, 7L, 7L, 2L, 5L, 3L, 4L, 6L, 7L, 1L, 5L, 1L, 6L, 4L, 5L, 3L, 6L, 4L, 8L, 1L, 3L, 4L, 6L, 7L, 3L, 2L, 6L, 4L, 2L, 1L, 7L, 4L, 8L, 2L, 3L, 2L, 5L, 8L, 2L, 8L, 3L, 3L, 5L, 6L, 7L, 1L, 5L, 6L, 4L, 2L, 6L, 7L, 1L, 5L, 7L, 2L), ypos = c(1L, 2L, 8L, 1L, 6L, 7L, 1L, 4L, 6L, 1L, 2L, 3L, 4L, 5L, 7L, 8L, 10L, 2L, 6L, 9L, 1L, 2L, 10L, 4L, 5L, 6L, 3L, 5L, 9L, 3L, 9L, 10L, 3L, 7L, 8L, 2L, 5L, 6L, 3L, 4L, 10L, 1L, 4L, 10L, 2L, 8L, 9L, 3L, 6L, 8L, 5L, 7L, 10L, 3L, 4L, 7L, 2L, 4L, 5L, 6L, 7L, 9L, 4L, 7L, 8L, 1L, 2L, 9L, 5L, 9L, 10L, 1L, 6L, 8L, 3L, 5L, 7L), blocknr = c(1L, 3L, 2L, 3L, 1L, 2L, 2L, 1L, 3L, 2L, 1L, 1L, 3L, 2L, 1L, 3L, 2L, 2L, 1L, 3L, 1L, 2L, 3L, 3L, 1L, 2L, 1L, 2L, 3L, 3L, 1L, 2L, 1L, 3L, 2L, 2L, 1L, 3L, 2L, 3L, 1L, 1L, 2L, 3L, 3L, 2L, 1L, 3L, 2L, 1L, 1L, 3L, 2L, 3L, 1L, 2L, 1L, 2L, 3L, 1L, 3L, 2L, 1L, 2L, 3L, 3L, 1L, 2L, 3L, 2L, 1L, 2L, 3L, 1L, 2L, 3L, 1L), cat = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), .Label = c("A", "B", "C"), class = "factor")), .Names = c("xpos", "ypos", "blocknr", "cat"), row.names = c(NA, -77L), class = "data.frame")I've made the following ggplot code to make 2D overview:ggplot(data=testData, aes(x=xpos,y=ypos))+geom_tile(aes(fill=cat), colour = "white")+scale_fill_manual(values = c('A' = '#F8766D','C' = '#8ABF54','B' = '#C1DDA5'))+geom_text(aes(x=xpos,y=ypos,label=blocknr),size=3)+coord_cartesian(ylim = c(0.5, ymax + 0.5)) +coord_cartesian(xlim = c(0.5, xmax + 0.5)) +scale_x_continuous(breaks=seq(1,xmax,1))+scale_y_continuous(breaks=seq(1,ymax,1))+#geom_polygon(aes(group=blocknr))+theme(axis.line = element_line(colour = "white"), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), panel.background = element_blank())which produces the following result:Now I would like to highlight each group of blocknrs by drawing a border around them as shown below:I've played around with geom_polygon, geom_path, but I can't quite find a way to do this. Is there a general way to achieve this in ggplot without constructing an algorithm to compute where each line should be and add those lines as a geom_segment? 解决方案 As far as I know, there is no way to do this with standard ggplot2 tile options. But it's not to much trouble to constuct them of you do it as segments. For exampleymax <- max(testData$ypos)xmax <- max(testData$xpos)m <- matrix(0, nrow=ymax, ncol=xmax)m[as.matrix(testData[,2:1])] <- testData[,3]Here we are basically taking all the row/col assignment data and creating a matrix that essentially looks like the plot but we will with the block numbers. Now, we will scan for the locations we need to add "wall" by looking for changes in the block numbers as we go across each row and column separately.has.breaks<-function(x) ncol(x)==2 & nrow(x)>0hw<-do.call(rbind.data.frame, Filter(has.breaks, Map(function(i,x) cbind(y=i,x=which(diff(c(0,x,0))!=0)), 1:nrow(m), split(m, 1:nrow(m)))))vw<-do.call(rbind.data.frame, Filter(has.breaks, Map(function(i,x) cbind(x=i,y=which(diff(c(0,x,0))!=0)), 1:ncol(m), as.data.frame(m))))And you can add calls to geom_segments to add the horizontal and vertical walls to the plot.ggplot(data=testData, aes(x=xpos,y=ypos))+geom_tile(aes(fill=cat), colour = "white")+scale_fill_manual(values = c('A' = '#F8766D','C' = '#8ABF54','B' = '#C1DDA5'))+geom_text(aes(x=xpos,y=ypos,label=blocknr),size=3)+geom_segment(data=hw, aes(x=x-.5, xend=x-.5, y=y-.5, yend=y+.5))+geom_segment(data=vw, aes(x=x-.5, xend=x+.5, y=y-.5, yend=y-.5))+coord_cartesian(ylim = c(0.4, ymax + 0.6)) +coord_cartesian(xlim = c(0.4, xmax + 0.6)) +scale_x_continuous(breaks=seq(1,xmax,1))+scale_y_continuous(breaks=seq(1,ymax,1))+theme(axis.line = element_line(colour = "white"), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), panel.background = element_blank())which gives 这篇关于叠加ggplot根据多余的因素将多边形边界的图块分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-22 21:19