Scatterplot со слишком большим количеством очков - PullRequest
113 голосов
/ 10 октября 2011

Я пытаюсь построить две переменные, где N = 700K.Проблема в том, что существует слишком много совпадений, так что сюжет становится в основном сплошным блоком черного цвета.Есть ли способ получить «облако» в градациях серого, в котором темнота графика является функцией количества точек в регионе?Другими словами, вместо того, чтобы показывать отдельные точки, я хочу, чтобы график был «облачным», причем чем больше точек в области, тем темнее эта область.

Ответы [ 7 ]

140 голосов
/ 10 октября 2011

Один из способов справиться с этим - альфа-смешение, которое делает каждую точку слегка прозрачной.Таким образом, области выглядят более темными, и на них нанесено больше точек.

Это легко сделать в ggplot2:

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

enter image description here

Другой удобный способиметь дело с этим (и, вероятно, более подходящим для количества точек, которые у вас есть) является гексагональным биннингом:

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

enter image description here

И есть также обычный старый прямоугольный биннинг (изображение опущено), которая больше похожа на вашу традиционную тепловую карту:

ggplot(df,aes(x=x,y=y)) + geom_bin2d()
57 голосов
/ 20 апреля 2013

Вы также можете взглянуть на пакет ggsubplot.В этом пакете реализованы функции, которые были представлены Хэдли Уикхемом в 2011 году (http://blog.revolutionanalytics.com/2011/10/ggplot2-for-big-data.html).

(далее я включаю слой "points" для иллюстрации).

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)

enter image description here

Тем не менее, эта функция содержит камни, если у вас есть третья переменная для управления.

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

enter image description here

Или можно использовать другой подход smoothScatter():

smoothScatter(dat[2:3])

enter image description here

51 голосов
/ 11 октября 2011

Альфа-смешивание легко сделать и с базовой графикой.

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

Первые шесть чисел после # - это цвета в шестнадцатеричном RGB, а последние два - непрозрачность, опять же в шестнадцатеричном, поэтому непрозрачность 33 ~ 3/16-ая.

enter image description here

45 голосов
/ 10 октября 2011

Вы также можете использовать линии контуров плотности (ggplot2):

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

enter image description here

Или объединить контуры плотности с альфа-смешиванием:

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

enter image description here

43 голосов
/ 26 сентября 2017

Обзор нескольких хороших вариантов в ggplot2:

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

Опция A: прозрачные точки

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

Опция B: добавление контуров плотности

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

Опция C: добавить заполненные контуры плотности

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

Опция D: карта плотности плотности

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

Опция E: hexbins

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

Опция F: коврики

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

Объединить в одну цифру:

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

enter image description here

28 голосов
/ 11 октября 2011

Вам может пригодиться пакет hexbin. Со страницы справки 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

0 голосов
/ 08 января 2019

Мой любимый метод построения данных такого типа - тот, который описан в этом вопросе - график плотности рассеяния .Идея состоит в том, чтобы сделать точечную диаграмму, но раскрасить точки их плотностью (грубо говоря, количеством совпадений в этой области).расположение выбросов, и

показывает любую структуру в плотной области графика.

Вот результат из верхнего ответа на связанный вопрос:

scatter-density plot

...