2012-10-31 34 views
11

Tôi muốn sử dụng stat_binhex() của ggplot2 để vẽ đồng thời hai biến độc lập trên cùng biểu đồ, mỗi biến có độ dốc màu riêng bằng cách sử dụng scale_colour_gradientn().ggplot2 nhiều stat_binhex() vẽ với các gradient màu khác nhau trong một hình ảnh

Nếu chúng ta bỏ qua thực tế là các đơn vị trục x không khớp, ví dụ có thể tái sản xuất sẽ vẽ đồ thị sau đây trong cùng một hình ảnh trong khi vẫn duy trì các gradient điền riêng biệt.

d <- ggplot(diamonds, aes(x=carat,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA) 
try(ggsave(plot=d,filename=<some file>,height=6,width=8)) 

enter image description here

d <- ggplot(diamonds, aes(x=depth,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA) 
try(ggsave(plot=d,filename=<some other file>,height=6,width=8)) 

enter image description here

Tôi tìm thấy một số cuộc nói chuyện của một vấn đề có liên quan trong nhóm ggplot2 google here.

Trả lời

10

Dưới đây là một giải pháp khả thi: Tôi đã lấy ý tưởng @ mnel của bản đồ bin đếm đến tính minh bạch alpha, và tôi đã biến x biến để họ có thể được vẽ trên các trục tương tự.

library(ggplot2) 

# Transforms range of data to 0, 1. 
rangeTransform = function(x) (x - min(x))/(max(x) - min(x)) 

dat = diamonds 
dat$norm_carat = rangeTransform(dat$carat) 
dat$norm_depth = rangeTransform(dat$depth) 

p1 = ggplot(data=dat) + 
    theme_bw() + 
    stat_binhex(aes(x=norm_carat, y=price, alpha=..count..), fill="#002BFF") + 
    stat_binhex(aes(x=norm_depth, y=price, alpha=..count..), fill="#FFD500") + 
    guides(fill=FALSE, alpha=FALSE) + 
    xlab("Range Transformed Units") 

ggsave(plot=p1, filename="plot_1.png", height=5, width=5) 

Suy nghĩ:

  1. tôi đã cố gắng (và thất bại) để hiển thị một huyền thoại màu/alpha hợp lý.Có vẻ khó khăn, nhưng nên có thể cho tất cả các tính năng tùy biến huyền thoại của ggplot2.

  2. Ghi nhãn đơn vị trục X cần một số loại giải pháp. Vẽ hai bộ đơn vị trên một trục được nhiều người cau mày, và ggplot2 không có tính năng như vậy.

  3. Giải thích các ô có màu chồng lên có vẻ rõ ràng trong ví dụ này, nhưng có thể rất lộn xộn tùy thuộc vào bộ dữ liệu được sử dụng và màu đã chọn.

  4. Nếu hai màu là phụ gia bổ sung, thì bất cứ nơi nào chúng trùng nhau, bạn sẽ thấy màu xám trung tính. Trường hợp chồng chéo là không bằng nhau, màu xám sẽ chuyển sang màu vàng hơn hoặc màu xanh hơn. Màu sắc của tôi không hoàn toàn bổ sung, đánh giá bởi màu hơi hơi hồng của các ô chồng chéo màu xám.

enter image description here

+0

Đây là hướng đi đúng. Bất kỳ ý tưởng về cách chỉ định một scale_fill_gradientn() cho mỗi stat_binhex()? Ngoài ra, suy nghĩ # 2 được lưu ý hợp lý - ứng dụng dự định của tôi sử dụng cùng một đơn vị cho cả hai biến x – metasequoia

+0

Bạn chỉ có thể có một tỷ lệ 'điền' trong mỗi lệnh gọi' ggplot'. Tôi có thể hình dung một số loại hack mà bạn định nghĩa 'scale_fill_manual' với các màu được chỉ định theo cách thủ công cho mỗi kết hợp của phạm vi giá trị * biến. Sau đó, mỗi lệnh gọi đến 'stat_binhex' sẽ ánh xạ' fill' thành một biến số cụ thể ... nhưng bây giờ tôi chỉ đang bập bẹ ... – bdemarest

5

Tôi nghĩ rằng những gì bạn muốn đi ngược lại các nguyên tắc của ggplot2 và ngữ pháp của phương pháp tiếp cận đồ họa nói chung hơn. Cho đến khi issue được giải quyết (mà tôi sẽ không giữ hơi thở của tôi), bạn có một vài lựa chọn

Sử dụng facet_wrapalpha

Đây là sẽ không sản xuất một đẹp huyền thoại, nhưng sẽ đưa bạn cách nọ cách kia để bạn muốn gì.

Bạn có thể thiết lập giá trị alpha để mở rộng bởi tính Frequency, truy cập bằng cách ..Frequency..

Tôi không nghĩ rằng bạn có thể kết hợp những huyền thoại độc đáo mặc dù.

library(reshape2) 
# in long format 
dm <- melt(diamonds, measure.var = c('depth','carat')) 

ggplot(dm, aes(y = price, fill = variable, x = value)) + 
    facet_wrap(~variable, ncol = 1, scales = 'free_x') + 
    stat_binhex(aes(alpha = ..count..), colour = 'grey80') + 
    scale_alpha(name = 'Frequency', range = c(0,1)) + 
    theme_bw() + 
    scale_fill_manual('Variable', values = setNames(c('darkblue','yellow4'), c('depth','carat'))) 

enter image description here

Sử dụng gridExtra với grid.arrange hoặc arrangeGrob

Bạn có thể tạo lô riêng biệt và sử dụng gridExtra::grid.arrange để sắp xếp trên một hình ảnh duy nhất.

d_carat <- ggplot(diamonds, aes(x=carat,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA) 

d_depth <- ggplot(diamonds, aes(x=depth,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA) 

library(gridExtra) 


grid.arrange(d_carat, d_depth, ncol =1) 

enter image description here

Nếu bạn muốn điều này để làm việc với ggsave (nhờ @bdemarest bình luận dưới đây và @baptiste)

thay grid.arrange với arrangeGrob một cái gì đó như thế nào.

ggsave(plot=arrangeGrob(d_carat, d_depth, ncol=1), filename="plot_2.pdf", height=12, width=8) 
+2

Bạn có thể sử dụng 'ggsave()' nếu bạn thay thế 'arrangeGrob' cho 'grid.arrange'. Ví dụ: 'ggsave (cốt truyện = sắp xếpGrob (d_carat, d_depth, ncol = 1), filename =" plot_2.pdf ", height = 12, width = 8)'. (@ baptiste đã chỉ ra điều này với tôi trong một nhận xét trước đó.) – bdemarest

+0

Cảm ơn @bdemarest, rất hữu ích. – mnel

+0

Câu trả lời đầu tiên có thể không còn hoạt động trên phiên bản ggplot mới hơn, xem [tại đây] (https://stackoverflow.com/questions/39446852/geom-hexbin-map-bincount-to-alpha/). – Axeman

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