2013-06-13 24 views
11

Lô phân tán có thể khó giải thích khi nhiều điểm trùng nhau, vì chồng chéo che khuất mật độ dữ liệu trong một vùng cụ thể. Một giải pháp là sử dụng màu sắc bán trong suốt cho các điểm được vẽ, do đó vùng mờ đục chỉ ra rằng nhiều quan sát có mặt trong các tọa độ đó.R Scatter Plot: màu biểu tượng đại diện cho số điểm chồng chéo

Dưới đây là một ví dụ về giải pháp màu đen và trắng của tôi trong R:

MyGray <- rgb(t(col2rgb("black")), alpha=50, maxColorValue=255) 
x1 <- rnorm(n=1E3, sd=2) 
x2 <- x1*1.2 + rnorm(n=1E3, sd=2) 
dev.new(width=3.5, height=5) 
par(mfrow=c(2,1), mar=c(2.5,2.5,0.5,0.5), ps=10, cex=1.15) 
plot(x1, x2, ylab="", xlab="", pch=20, col=MyGray) 
plot(x1, x2, ylab="", xlab="", pch=20, col="black") 

The advantages of using opacity to indicate point density

Tuy nhiên, thời gian gần đây tôi đi qua this article in PNAS, diễn một cách tiếp cận tương tự, nhưng sử dụng bản đồ nhiệt màu trái ngược với độ mờ đục như một chỉ báo về số điểm trùng nhau. Bài viết là Truy cập Mở, vì vậy bất kỳ ai cũng có thể tải xuống tệp .pdf và xem Hình 1, trong đó có một ví dụ có liên quan của biểu đồ tôi muốn tạo. Phần phương pháp của bài báo này chỉ ra rằng các phân tích đã được thực hiện trong Matlab.

Vì lợi ích của sự thuận tiện, đây là một phần nhỏ của hình 1 từ bài viết ở trên:

Figure 1 from Flombaum et al. 2013, PNAS

Làm thế nào tôi sẽ tạo ra một biểu đồ phân tán trong R được sử dụng màu sắc, không mờ, như một chỉ báo mật độ điểm?

Để bắt đầu, người dùng R có thể truy cập lược đồ màu Matlab này trong thư viện install.packages("fields"), sử dụng hàm tim.colors().

Có cách nào dễ dàng để tạo một hình tương tự như Hình 1 của bài viết trên, nhưng trong R? Cảm ơn!

Trả lời

26

Một tùy chọn là sử dụng densCols() để trích xuất mật độ hạt nhân tại mỗi điểm. Lập bản đồ mật độ đó với đoạn đường màu mong muốn, và vẽ các điểm theo thứ tự tăng mật độ cục bộ sẽ giúp bạn có một âm mưu giống như những điểm trong bài viết được liên kết.

## Data in a data.frame 
x1 <- rnorm(n=1E3, sd=2) 
x2 <- x1*1.2 + rnorm(n=1E3, sd=2) 
df <- data.frame(x1,x2) 

## Use densCols() output to get density at each point 
x <- densCols(x1,x2, colramp=colorRampPalette(c("black", "white"))) 
df$dens <- col2rgb(x)[1,] + 1L 

## Map densities to colors 
cols <- colorRampPalette(c("#000099", "#00FEFF", "#45FE4F", 
          "#FCFF00", "#FF9400", "#FF3100"))(256) 
df$col <- cols[df$dens] 

## Plot it, reordering rows so that densest points are plotted on top 
plot(x2~x1, data=df[order(df$dens),], pch=20, col=col, cex=2) 

enter image description here

+0

+10 Sẽ bỏ phiếu cao hơn nếu tôi có thể. –

+0

Điều này có vẻ chính xác là câu trả lời mà tôi đã hy vọng ... cảm ơn! – rbatt

+0

@JoshOBrien: Thật tuyệt vời! Hai câu hỏi: 1) Làm thế nào bạn có thể thêm hình ảnh vào đây trong câu trả lời của bạn? 2) Cách thêm chú giải vào đây? – Shambho

3

Bạn có thể sử dụng smoothScatter cho việc này.

colramp = colorRampPalette(c('white', 'blue', 'green', 'yellow', 'red')) 
smoothScatter(x1, x2, colramp=colramp) 
+0

Cảm ơn đã trả lời - Đây là khoảng ý tưởng đúng, nhưng tôi muốn để tránh làm mịn của các điểm. Tôi đã cố gắng chơi với băng thông vv, nhưng nó không có vẻ như chức năng này sẽ có thể duy trì các điểm cá nhân. – rbatt

+0

Rất đẹp! Không biết về hàm này hoặc hàm 'densCols()' có liên quan mà tôi đã sử dụng trong câu trả lời vừa nãy. –

5

Bạn có thể nhận được hiệu ứng tương tự bằng cách làm hình lục giác, chia vùng thành hình lục giác, tô màu mỗi hình lục giác dựa trên số điểm trong hình lục giác. Gói hexbin có các chức năng để thực hiện việc này và cũng có các chức năng trong gói ggplot2.

+1

Chức năng nào trong ggplot2 thực hiện điều này? – rbatt

+0

@rbatt, xem 'stat_binhex'. –

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