R точечная диаграмма: цвет символа представляет количество перекрывающихся точек

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

Ниже приведен пример моего черно-белого решения в 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

однако, я недавно наткнулся в данной статье в PNAS, который принял аналогичный подход, но использовал окраску тепловой карты в отличие от непрозрачности в качестве индикатора того, сколько точек перекрывались. Статья открытый доступ, поэтому любой желающий может скачать .pdf и посмотрите на Рисунок 1, который содержит соответствующий пример графика, который я хочу создать. В разделе методы этой статьи указано, что анализы проводились в Matlab.

для удобства, вот небольшая часть рисунка 1 из вышеизложенного статья:

Figure 1 from Flombaum et al. 2013, PNAS

как создать диаграмму рассеяния в R, которая использовала бы цвет, а не непрозрачность, в качестве индикатора плотности точек?

для начала пользователи R могут получить доступ к этой цветовой схеме Matlab в install.packages("fields") библиотеки, используя функцию tim.colors().

есть ли простой способ сделать фигуру, похожую на Рисунок 1 вышеуказанной статьи, но в R? Спасибо!

3 ответов


один из вариантов-использовать densCols() для извлечения плотности ядра в каждой точке. Сопоставление этих плотностей с желаемой цветовой рампой и построение точек в порядке увеличения локальной плотности дает вам график, очень похожий на те, что в связанной статье.

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


вы можете получить аналогичный эффект, выполнив шестиугольное биннинг, разделить область на шестиугольники, покрасить каждый шестиугольник на основе количества точек в шестиугольнике. Пакет hexbin имеет функции для этого, а также функции в пакете ggplot2.


можно использовать smoothScatter для этого.

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