Scatterplot со слишком большим количеством очков
Я пытаюсь построить две переменные, где N=700K. Проблема в том, что существует слишком много совпадений, так что сюжет становится в основном сплошным блоком черного цвета. Есть ли способ получить "облако" в градациях серого, где темнота графика является функцией количества точек в регионе? Другими словами, вместо того, чтобы показывать отдельные точки, я хочу, чтобы график был "облаком", причем чем больше точек в области, тем темнее эта область.
6 ответов
Один из способов справиться с этим - альфа-смешение, которое делает каждую точку слегка прозрачной. Таким образом, области выглядят более темными, и на них нанесено больше точек.
Это легко сделать в ggplot2
:
df <- data.frame(x = rnorm(5000),y=rnorm(5000))
ggplot(df,aes(x=x,y=y)) + geom_point(alpha = 0.3)
Другой удобный способ справиться с этим (и, возможно, более подходящий для количества имеющихся у вас точек) - это шестиугольное биннинг:
ggplot(df,aes(x=x,y=y)) + stat_binhex()
И есть также обычный старый прямоугольный биннинг (изображение опущено), который больше похож на вашу традиционную тепловую карту:
ggplot(df,aes(x=x,y=y)) + geom_bin2d()
Обзор нескольких хороших вариантов в ggplot2
:
library(ggplot2)
x <- rnorm(n = 10000)
y <- rnorm(n = 10000, sd=2) + x
df <- data.frame(x, y)
Вариант А: прозрачные точки
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 = ..level..), geom = 'polygon') +
scale_fill_viridis_c(name = "density") +
geom_point(shape = '.')
Вариант D: тепловая карта плотности
o4 <- ggplot(df, aes(x, y)) +
stat_density_2d(aes(fill = ..density..), geom = 'raster', contour = FALSE) +
scale_fill_viridis_c() +
coord_cartesian(expand = FALSE) +
geom_point(shape = '.', col = 'white')
Вариант E: гексбины
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')
Вы также можете взглянуть на 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)
Тем не менее, это показывает камни, если у вас есть третья переменная для контроля.
# 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)
Или другой подход будет использовать smoothScatter()
:
smoothScatter(dat[2:3])
Альфа-смешивание легко сделать с базовой графикой.
df <- data.frame(x = rnorm(5000),y=rnorm(5000))
with(df, plot(x, y, col="#00000033"))
Первые шесть чисел после #
это цвет в шестнадцатеричном RGB, а последние два - непрозрачность, опять же в шестнадцатеричном, поэтому 33 ~ 3/16-й непрозрачный.
Вы также можете использовать контурные линии плотности (ggplot2
):
df <- data.frame(x = rnorm(15000),y=rnorm(15000))
ggplot(df,aes(x=x,y=y)) + geom_point() + geom_density2d()
Или объедините контуры плотности с альфа-смешиванием:
ggplot(df,aes(x=x,y=y)) +
geom_point(colour="blue", alpha=0.2) +
geom_density2d(colour="black")
Вы можете найти полезным 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)
geom_pointdenisty
из ggpointdensity
пакет (недавно разработанный Лукасом Кремером и Саймоном Андерсом (2019)) позволяет визуализировать плотность и отдельные точки данных одновременно:
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()
Мой любимый метод построения данных такого типа - это метод, описанный в этом вопросе, - график плотности рассеяния. Идея состоит в том, чтобы сделать точечную диаграмму, но раскрасить точки их плотностью (грубо говоря, количеством совпадений в этой области).
Это одновременно:
- четко показывает расположение выбросов, и
- выявляет любую структуру в плотной области участка.
Вот результат из верхнего ответа на связанный вопрос: