Scatterplot có quá nhiều điểm


126

Tôi đang cố gắng vẽ hai biến trong đó N = 700K. Vấn đề là có quá nhiều sự chồng chéo, do đó cốt truyện trở thành một khối đen đặc. Có cách nào để có một "đám mây" thang độ xám trong đó bóng tối của cốt truyện là một hàm của số điểm trong một vùng không? Nói cách khác, thay vì hiển thị các điểm riêng lẻ, tôi muốn cốt truyện là một "đám mây", với số lượng điểm trong một khu vực càng nhiều, khu vực đó càng tối.


4
Nghe có vẻ như bạn đang tìm kiếm một bản đồ nhiệt: Flowdata.com/2010/01/21/ từ

Câu trả lời:


145

Một cách để giải quyết vấn đề này là trộn alpha, làm cho mỗi điểm hơi trong suốt. Vì vậy, các vùng xuất hiện tối hơn có nhiều điểm được vẽ trên chúng.

Điều này rất dễ thực hiện trong ggplot2:

df <- data.frame(x = rnorm(5000),y=rnorm(5000))
ggplot(df,aes(x=x,y=y)) + geom_point(alpha = 0.3)

nhập mô tả hình ảnh ở đây

Một cách thuận tiện khác để giải quyết vấn đề này là (và có lẽ phù hợp hơn với số điểm bạn có) là tạo hình lục giác:

ggplot(df,aes(x=x,y=y)) + stat_binhex()

nhập mô tả hình ảnh ở đây

Và cũng có binning hình chữ nhật cũ thông thường (hình ảnh bị bỏ qua), giống như bản đồ nhiệt truyền thống của bạn:

ggplot(df,aes(x=x,y=y)) + geom_bin2d()

1
Làm thế nào tôi có thể thay đổi màu sắc? Bây giờ tôi đang chuyển từ màu xanh sang màu đen, trong khi tôi muốn lấy reg, thang màu xanh xanh.
user1007742

@ user1007742 Sử dụng scale_fill_gradient()và chỉ định màu thấp và cao của riêng bạn hoặc sử dụng scale_fill_brewer()và chọn từ một trong các bảng màu liên tiếp.
Joran

@joran cảm ơn, đó là làm việc bây giờ. Làm thế nào về việc thay đổi loại / hình dạng của các điểm? Tôi nhận được hình lục giác hoặc hình vuông. Tôi chỉ muốn chấm đơn giản. Khi tôi sử dụng geom_point (), nó sẽ báo lỗi.
dùng1007742

1
@ user1007742 Chà, nó được gọi là "binning hexagonal" vì một lý do! ;) Nó không vẽ "điểm", nó chia toàn bộ khu vực thành các thùng hình lục giác (hoặc hình chữ nhật) và sau đó chỉ đơn giản là tô màu các thùng dựa trên số lượng điểm trong thùng đó. Vì vậy, câu trả lời ngắn gọn là "bạn không thể". Nếu bạn muốn các hình dạng khác nhau, bạn phải sử dụng geom_point()và vẽ từng điểm riêng lẻ.
Joran

Nếu tôi có dữ liệu 3D thì sao?
skan

60

Bạn cũng có thể có một cái nhìn vào ggsubplotgói. Gói này triển khai các tính năng được Hadley Wickham trình bày vào năm 2011 ( http://blog.revolutionanalytics.com/2011/10/ggplot2-for-big-data.html ).

(Trong phần sau đây, tôi bao gồm "điểm" -layer cho mục đích minh họa.)

library(ggplot2)
library(ggsubplot)

# Make up some data
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=5000),
                  xvar = c(rep(1:20,250) + rnorm(5000,sd=5),rep(16:35,250) + rnorm(5000,sd=5)),
                  yvar = c(rep(1:20,250) + rnorm(5000,sd=5),rep(16:35,250) + rnorm(5000,sd=5)))


# Scatterplot with subplots (simple)
ggplot(dat, aes(x=xvar, y=yvar)) +
  geom_point(shape=1) +
  geom_subplot2d(aes(xvar, yvar,
                     subplot = geom_bar(aes(rep("dummy", length(xvar)), ..count..))), bins = c(15,15), ref = NULL, width = rel(0.8), ply.aes = FALSE)

nhập mô tả hình ảnh ở đây

Tuy nhiên, tính năng này đá nếu bạn có một biến thứ ba để kiểm soát.

# Scatterplot with subplots (including a third variable) 

ggplot(dat, aes(x=xvar, y=yvar)) +
  geom_point(shape=1, aes(color = factor(cond))) +
  geom_subplot2d(aes(xvar, yvar,
                     subplot = geom_bar(aes(cond, ..count.., fill = cond))),
                 bins = c(15,15), ref = NULL, width = rel(0.8), ply.aes = FALSE)  

nhập mô tả hình ảnh ở đây

Hoặc một cách tiếp cận khác sẽ được sử dụng smoothScatter():

smoothScatter(dat[2:3])

nhập mô tả hình ảnh ở đây


3
cốt truyện thứ hai thật tuyệt!
Ricardo Saporta

Nếu tôi có dữ liệu 3D thì sao?
skan

2
@ skan: Bạn có thể mở một câu hỏi mới cho điều đó.
hùng vĩ

Thật không may, gói gssubplot không được duy trì nữa và bị xóa khỏi cran repo ... bạn có biết một gói thay thế có thể được sử dụng để tạo ra các lô như hai phần đầu ở trên không?
dieHellste

Nếu bạn sử dụng phiên bản cũ của R & ggplot2, bạn sẽ có thể làm cho nó hoạt động
hoành tráng vào

59

Tổng quan về một số tùy chọn tốt trong ggplot2:

library(ggplot2)
x <- rnorm(n = 10000)
y <- rnorm(n = 10000, sd=2) + x
df <- data.frame(x, y)

Tùy chọn A: điểm trong suốt

o1 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.05)

Tùy chọn B: thêm đường viền mật độ

o2 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.05) +
  geom_density_2d()

Tùy chọn C: thêm đường viền mật độ đầy

o3 <- ggplot(df, aes(x, y)) +
  stat_density_2d(aes(fill = stat(level)), geom = 'polygon') +
  scale_fill_viridis_c(name = "density") +
  geom_point(shape = '.')

Tùy chọn D: mật độ nhiệt

o4 <- ggplot(df, aes(x, y)) +
  stat_density_2d(aes(fill = stat(density)), geom = 'raster', contour = FALSE) +       
  scale_fill_viridis_c() +
  coord_cartesian(expand = FALSE) +
  geom_point(shape = '.', col = 'white')

Tùy chọn E: hexbins

o5 <- ggplot(df, aes(x, y)) +
  geom_hex() +
  scale_fill_viridis_c() +
  geom_point(shape = '.', col = 'white')

Tùy chọn F: thảm

o6 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.1) +
  geom_rug(alpha = 0.01)

Kết hợp trong một hình:

cowplot::plot_grid(
  o1, o2, o3, o4, o5, o6,
  ncol = 2, labels = 'AUTO', align = 'v', axis = 'lr'
)

nhập mô tả hình ảnh ở đây


1
Đây là một câu trả lời được đặt ra rất độc đáo mà tôi nghĩ rằng nó xứng đáng được tăng thêm một chút.
Lalochezia

Cung cấp cho tôi một lỗi Lỗi trong scale_fill_viridis_c (): không thể tìm thấy hàm "scale_fill_viridis_c"
JustGettinStarted

cập nhật ggplot2, cài đặt lại ggplot2 và tải lại ggplot2. Không sửa lỗi. Gói 'viridis' được cài đặt riêng biệt và cho phép tôi sử dụng chức năng 'scale_fill_viridis' nhưng không phải là 'scale_fill_viridis_c' vẫn gây ra lỗi tương tự
JustGettinStarted

oh tôi tin bạn Không có vấn đề ở đó. Chỉ cần cố gắng để đi đến tận cùng của lỗi.
JustGettin Bắt đầu

51

Pha trộn Alpha rất dễ thực hiện với đồ họa cơ bản là tốt.

df <- data.frame(x = rnorm(5000),y=rnorm(5000))
with(df, plot(x, y, col="#00000033"))

Sáu số đầu tiên sau #màu là hex hex và hai số cuối là độ mờ, một lần nữa ở hex, do đó mờ đục 33 ~ 3/16.

nhập mô tả hình ảnh ở đây


20
Chỉ cần thêm một chút bối cảnh, "# 000000" là màu đen và "33" được thêm vào cuối màu là mức độ mờ đục --- ở đây, 33%.
Charlie

Cảm ơn đã giải thích thêm.
Aaron rời Stack Overflow

Làm cho cảm giác hoàn hảo. Cảm ơn, cả Aaron và Charlie.
dùng702432

12
Ghi chú nhỏ; các số ở dạng hex nên 33 thực sự mờ đục 3/16.
Aaron rời Stack Overflow

45

Bạn cũng có thể sử dụng các đường đồng mức mật độ ( ggplot2):

df <- data.frame(x = rnorm(15000),y=rnorm(15000))
ggplot(df,aes(x=x,y=y)) + geom_point() + geom_density2d()

nhập mô tả hình ảnh ở đây

Hoặc kết hợp các đường viền mật độ với pha trộn alpha:

ggplot(df,aes(x=x,y=y)) + 
    geom_point(colour="blue", alpha=0.2) + 
    geom_density2d(colour="black")

nhập mô tả hình ảnh ở đây


29

Bạn có thể tìm thấy hexbingói hữu ích . Từ trang trợ giúp của hexbinplot:

library(hexbin)
mixdata <- data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)),
                      y = c(rnorm(5000),rnorm(5000,2,3)),
                      a = gl(2, 5000))
hexbinplot(y ~ x | a, mixdata)

hexbinplot


+1 hexbin là giải pháp ưa thích của tôi - nó có thể lấy một số điểm lớn và sau đó tạo một cốt truyện một cách an toàn. Tôi không chắc chắn rằng những người khác sẽ không cố gắng tạo ra một cốt truyện, mà chỉ đơn giản là che giấu những thứ khác nhau.
Lặp lại

Bất cứ điều gì như hexbin cho dữ liệu 3D?
skan

8

geom_pointdenistytừ ggpointdensitygói (được phát triển gần đây bởi Lukas Kremer và Simon Anders (2019)) cho phép bạn hình dung mật độ và các điểm dữ liệu riêng lẻ cùng một lúc:

library(ggplot2)
# install.packages("ggpointdensity")
library(ggpointdensity)

df <- data.frame(x = rnorm(5000), y = rnorm(5000))
ggplot(df, aes(x=x, y=y)) + geom_pointdensity() + scale_color_viridis_c()


2

Phương pháp ưa thích của tôi để vẽ loại dữ liệu này là phương pháp được mô tả trong câu hỏi này - một biểu đồ mật độ phân tán . Ý tưởng là thực hiện một biểu đồ phân tán nhưng tô màu các điểm theo mật độ của chúng (nói một cách đại khái, số lượng chồng lấp trong khu vực đó).

Nó đồng thời:

  • cho thấy rõ vị trí của các ngoại lệ, và
  • cho thấy bất kỳ cấu trúc trong khu vực dày đặc của cốt truyện.

Đây là kết quả từ câu trả lời hàng đầu cho câu hỏi được liên kết:

âm mưu phân tán mật độ


1
Đây là cách yêu thích của tôi quá. Xem câu trả lời của tôi để làm thế nào để đạt được điều này trong R.
jan-glx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.