2014-09-06 1 views
3

у меня есть фрейм данных с й и у позиции и два фактора столбцов blocknr и кот:Overlay ggplot сгруппированных плитки с полигоном границы в зависимости от дополнительного фактора

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") 

я сделал следующий ggplot код, чтобы сделать 2D Обзор:

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()) 

, который производит следующий результат: enter image description here

Теперь я хотел бы выделить каждую группу blocknrs по рисуя рамку вокруг них, как показано ниже: enter image description here

Я играл с geom_polygon, geom_path, но я не могу достаточно найти способ сделать это. Есть ли общий способ достичь этого в ggplot без построения алгоритма для вычисления, где должна быть каждая строка, и добавить эти строки как geom_segment?

ответ

5

Насколько я знаю, нет возможности сделать это со стандартными параметрами плитки ggplot2. Но не стоит беспокоиться о том, чтобы вы делали это как сегменты. Например

ymax <- max(testData$ypos) 
xmax <- max(testData$xpos) 

m <- matrix(0, nrow=ymax, ncol=xmax) 
m[as.matrix(testData[,2:1])] <- testData[,3] 

Здесь мы в основном принимаем все данные о назначении строк/Col и создании матрицы, которая по существу выглядит как сюжет, но мы будем с номерами блоков. Теперь мы сканируем места, где нам нужно добавить «стену», ища изменения номеров блоков, когда мы переходим по каждой строке и столбцу отдельно.

has.breaks<-function(x) ncol(x)==2 & nrow(x)>0 

hw<-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)))) 

И вы можете добавлять вызовы в geom_segments, чтобы добавить горизонтальные и вертикальные стены к сюжету.

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()) 

который дает

enter image description here

+0

красивый и элегантный обходной путь/решение! Благодаря! – svdwoude