【发布时间】:2011-12-04 14:34:21
【问题描述】:
我正在尝试绘制 N=700K 的两个变量。问题是重叠太多,以至于情节主要变成了黑色的实心块。有没有办法得到一个灰度“云”,其中情节的黑暗是一个区域中点数的函数?换句话说,我希望绘图是一个“云”,而不是显示单个点,一个区域中的点数越多,该区域越暗。
【问题讨论】:
-
听起来您正在寻找热图:flowingdata.com/2010/01/21/…
标签: r scatter-plot
我正在尝试绘制 N=700K 的两个变量。问题是重叠太多,以至于情节主要变成了黑色的实心块。有没有办法得到一个灰度“云”,其中情节的黑暗是一个区域中点数的函数?换句话说,我希望绘图是一个“云”,而不是显示单个点,一个区域中的点数越多,该区域越暗。
【问题讨论】:
标签: r scatter-plot
ggpointdensity package 中的geom_pointdenisty(最近由 Lukas Kremer 和 Simon Anders(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()
【讨论】:
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)
o2 <- ggplot(df, aes(x, y)) +
geom_point(alpha = 0.05) +
geom_density_2d()
o3 <- ggplot(df, aes(x, y)) +
stat_density_2d(aes(fill = stat(level)), geom = 'polygon') +
scale_fill_viridis_c(name = "density") +
geom_point(shape = '.')
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')
o5 <- ggplot(df, aes(x, y)) +
geom_hex() +
scale_fill_viridis_c() +
geom_point(shape = '.', col = 'white')
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'
)
【讨论】:
我最喜欢绘制此类数据的方法是this question 中描述的一种方法 - 散点密度图。这个想法是做一个散点图,但根据它们的密度(粗略地说,该区域的重叠量)对点进行着色。
同时:
这是链接问题的最佳答案的结果:
【讨论】:
R 中实现这一点。
Alpha 混合也很容易与基本图形一起使用。
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()
或者将密度轮廓与 alpha 混合相结合:
ggplot(df,aes(x=x,y=y)) +
geom_point(colour="blue", alpha=0.2) +
geom_density2d(colour="black")
【讨论】:
您还可以查看ggsubplot 包。该软件包实现了 Hadley Wickham 在 2011 年 (http://blog.revolutionanalytics.com/2011/10/ggplot2-for-big-data.html) 提出的功能。
(在下文中,出于说明目的,我包括了“点”层。)
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])
【讨论】:
您可能会发现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)
【讨论】:
解决此问题的一种方法是使用 Alpha 混合,这会使每个点略微透明。因此,绘制更多点的区域显得更暗。
这在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()
【讨论】:
scale_fill_gradient() 并指定您自己的低色和高色,或使用scale_fill_brewer() 并从连续调色板之一中进行选择。
geom_point() 并绘制每个单独的点。