2015-02-12 20 views
8

Tôi đang tìm cách để điền đầy đủ vào các đường viền được tạo ra bởi stat_contour của ggplot2. Kết quả hiện nay là như thế này:Làm thế nào để điền vào các đường viền đầy đủ bằng cách sử dụng stat_contour

# Generate data 
library(ggplot2) 
library(reshape2) # for melt 
volcano3d <- melt(volcano) 
names(volcano3d) <- c("x", "y", "z") 

v <- ggplot(volcano3d, aes(x, y, z = z)) 
v + stat_contour(geom="polygon", aes(fill=..level..)) 

enter image description here

kết quả mong muốn có thể được sản xuất bằng cách thủ công chỉnh sửa các mã như sau.

v + stat_contour(geom="polygon", aes(fill=..level..)) + 
    theme(panel.grid=element_blank())+ # delete grid lines 
    scale_x_continuous(limits=c(min(volcano3d$x),max(volcano3d$x)), expand=c(0,0))+ # set x limits 
    scale_y_continuous(limits=c(min(volcano3d$y),max(volcano3d$y)), expand=c(0,0))+ # set y limits 
    theme(panel.background=element_rect(fill="#132B43")) # color background 

enter image description here

Câu hỏi của tôi: là có một cách để điền đầy đủ các âm mưu mà không tự xác định màu hoặc sử dụng geom_tile()?

+0

liên quan: http://stackoverflow.com/questions/25788727/filled-contour-vs-ggplot2-stat-contour – tonytonov

+0

Theo như tôi có thể nói, bạn sẽ cần phải mở rộng của bạn tập dữ liệu theo cách thủ công. Giải pháp của bạn trông đơn giản hơn, vì vậy nếu bạn hài lòng với nó, hãy để nó trở thành. – tonytonov

+0

Tôi thấy rằng bài viết quá nhưng geom_tile() sử dụng hình chữ nhật nhỏ và do đó, nó không phải là hiệu ứng tôi đang tìm kiếm. filled.contour đã tạo ra kết quả tốt nhất cho đến bây giờ nhưng sự không tương thích của nó với nhiều âm mưu đã dẫn tôi đến thử với ggplots. Tôi tự hỏi điều gì đã tạo ra những vùng trong suốt. – chengvt

Trả lời

9

Vì @tonytonov đã đề xuất thread này, các khu vực trong suốt có thể bị xóa bằng cách đóng các đa giác.

# check x and y grid 
minValue<-sapply(volcano3d,min) 
maxValue<-sapply(volcano3d,max) 
arbitaryValue=min(volcano3d$z-10) 

test1<-data.frame(x=minValue[1]-1,y=minValue[2]:maxValue[2],z=arbitaryValue) 
test2<-data.frame(x=minValue[1]:maxValue[1],y=minValue[2]-1,z=arbitaryValue) 
test3<-data.frame(x=maxValue[1]+1,y=minValue[2]:maxValue[2],z=arbitaryValue) 
test4<-data.frame(x=minValue[1]:maxValue[1],y=maxValue[2]+1,z=arbitaryValue) 
test<-rbind(test1,test2,test3,test4) 

vol<-rbind(volcano3d,test) 

w <- ggplot(vol, aes(x, y, z = z)) 
w + stat_contour(geom="polygon", aes(fill=..level..)) # better 

# Doesn't work when trying to get rid of unwanted space 
w + stat_contour(geom="polygon", aes(fill=..level..))+ 
    scale_x_continuous(limits=c(min(volcano3d$x),max(volcano3d$x)), expand=c(0,0))+ # set x limits 
    scale_y_continuous(limits=c(min(volcano3d$y),max(volcano3d$y)), expand=c(0,0)) # set y limits 

# work here! 
w + stat_contour(geom="polygon", aes(fill=..level..))+ 
coord_cartesian(xlim=c(min(volcano3d$x),max(volcano3d$x)), 
       ylim=c(min(volcano3d$y),max(volcano3d$y))) 

enter image description here

Vấn đề vẫn với tinh chỉnh này là tìm phương pháp ngoài việc thử và sai để xác định arbitaryValue.

[sửa từ đây]

Chỉ cần cập nhật nhanh để hiển thị như thế nào tôi xác định arbitaryValue mà không cần phải đoán cho mỗi bộ dữ liệu.

BINS<-50 
BINWIDTH<-(diff(range(volcano3d$z))/BINS) # reference from ggplot2 code 
arbitaryValue=min(volcano3d$z)-BINWIDTH*1.5 

Điều này có vẻ hoạt động tốt đối với tập dữ liệu tôi đang làm việc ngay bây giờ. Không chắc chắn nếu áp dụng với những người khác. Ngoài ra, lưu ý rằng thực tế là tôi đặt giá trị BINS ở đây yêu cầu tôi sẽ phải sử dụng bins=BINS trong stat_contour.

+0

Vui vì tôi có thể giúp. Giải pháp tốt đẹp, đặc biệt là với những hiện vật khó chịu mà bây giờ đã biến mất. Cảm ơn vì đăng! – tonytonov

0

Cảm ơn câu trả lời của @ chengvt. Đôi khi tôi cần kỹ thuật này, vì vậy tôi đã thực hiện tổng quát function().

test_f <- function(df) { 
    colname <- names(df) 
    names(df) <- c("x", "y", "z") 
    Range <- as.data.frame(sapply(df, range)) 
    Dim <- as.data.frame(t(sapply(df, function(x) length(unique(x))))) 
    arb_z = Range$z[1] - diff(Range$z)/20 
    df2 <- rbind(df, 
       expand.grid(x = c(Range$x[1] - diff(Range$x)/20, Range$x[2] + diff(Range$x)/20), 
          y = seq(Range$y[1], Range$y[2], length = Dim$y), z = arb_z), 
       expand.grid(x = seq(Range$x[1], Range$x[2], length = Dim$x), 
          y = c(Range$y[1] - diff(Range$y)/20, Range$y[2] + diff(Range$y)/20), z = arb_z)) 
    g <- ggplot(df2, aes(x, y, z = z)) + labs(x = colname[1], y = colname[2], fill = colname[3]) + 
    stat_contour(geom="polygon", aes(fill=..level..)) + 
    coord_cartesian(xlim=c(Range$x), ylim=c(Range$y), expand = F) 
    return(g) 
} 

library(ggplot2); library(reshape2) 
volcano3d <- melt(volcano) 
names(volcano3d) <- c("xxx", "yyy", "zzz") 
test_f(volcano3d) + scale_fill_gradientn(colours = terrain.colors(10)) 

enter image description here

Các vấn đề liên quan