【问题标题】:How can I overlay two dense scatter plots so that I can see the outlines of each in R or Matlab?如何叠加两个密集的散点图,以便在 R 或 Matlab 中看到每个散点图的轮廓?
【发布时间】:2012-03-14 17:18:58
【问题描述】:

看这个例子

这是在 matlab 中通过独立制作两个散点图创建的,每个创建图像,然后使用 imagesc 将它们绘制成同一个图形,最后将顶部图像的 alpha 设置为 0.5。

我想在 R 或 matlab 中执行此操作而不使用图像,因为创建图像不会保留轴比例信息,也不能覆盖网格(例如,在 matlab 中使用“grid on”)。理想情况下,我希望在 matlab 中正确执行此操作,但也会对 R 中的解决方案感到满意。这似乎应该是可能的,但我一生都无法弄清楚。

所以一般来说,我希望能够设置整个绘制对象的 alpha(即 matlab 用语中的 matlab 绘图句柄......)

谢谢,

本。

编辑:上例中的数据实际上是二维的。绘制的点来自计算机模拟。每个点代表“幅度”(y 轴)(特定于我正在运行的模拟的紧急属性),针对“性能”(x 轴)绘制。

编辑 2:每个数据集中有 1796400 个点。

【问题讨论】:

  • 我没有一个很好的解决方案(在 ggplot 中),除了说虽然我确信你“必须”使用散点图是有原因的,但你可能应该只覆盖两个此处的密度估计,这使得使用 alpha 级别的解决方案变得非常简单。
  • 为每个点创建一个变量以确定它位于哪个集合:A、B 或两者。使用它来选择颜色。
  • 不是微不足道的,但是将来自两组六边形箱的信息组合起来怎么样?
  • 一个蛮力解决方案是:(i)创建两个具有相同范围、轴等的单独图; (ii) 使用 grid.cap() 捕捉两者的栅格表示; (iii) 将栅格中的值转换为整数; (iv) 添加一个栅格加上另一个栅格的 10 倍; (v) 用适当的颜色名称替换结果栅格中的整数;然后 (vi) 用 grid.raster( , interpolate=FALSE) 绘制它。如果您想经常这样做,那么编写一个小函数来为您传递给它的任何一对绘图调用执行这些步骤可能是值得的。
  • 我编辑了我的原始帖子以解释正在绘制的数据类型。我不相信生成 2D 密度估计,就像你可能建议 Joran 那样,真的会产生我希望做的事情,因为这会导致每个数据集有多个轮廓。我想我想要每个数据集周围有一个轮廓,以便保留每个数据集的一般形状;通过这种方式,我可以摆脱各个点,这将是很好的。今天是我第一次做任何 R - 花了我一段时间来搞清楚......

标签: r matlab plot ggplot2 plyr


【解决方案1】:

使用ggplot2,您可以将两个geom_point 相加,并使用alpha 参数使它们透明。 ggplot2 als 增加了透明度,我认为这就是你想要的。这应该可以工作,虽然我还没有运行它。

dat = data.frame(x = runif(1000), y = runif(1000), cat = rep(c("A","B"), each = 500))
ggplot(aes(x = x, y = y, color = cat), data = dat) + geom_point(alpha = 0.3)

ggplot2 太棒了!

这是一个计算和绘制凸包的例子:

library(automap)
library(ggplot2)
library(plyr)
loadMeuse()
theme_set(theme_bw())

meuse = as.data.frame(meuse)
chull_per_soil = ddply(meuse, .(soil), 
           function(sub) sub[chull(sub$x, sub$y),c("x","y")])

ggplot(aes(x = x, y = y), data = meuse) +
  geom_point(aes(size = log(zinc), color = ffreq)) +
  geom_polygon(aes(color = soil), data = chull_per_soil, fill = NA) +
  coord_equal()

导致下图:

【讨论】:

  • 谢谢 Paul,--不幸的是,由于我绘制的每一类数据都非常密集(每个数据集中有 1796400 个点),每组中的许多点重叠,因此有效地消除了最密集的地区。这意味着“顶部”数据集中的密集区域通常太不透明,无法看到下方数据集中的任何点。
  • 您可以对数据进行二次抽样。或者在连接点周围绘制一个凸包并使用透明geom_polygon's
  • 我认为凸包是前进的方向。干杯。
  • 我添加了一个如何在 R 中创建和绘制凸包的示例。
  • :),meuse 数据集是多功能的 :)
【解决方案2】:

您可以先将两个数据集导出为位图图像,然后重新导入它们,添加透明度:

library(grid)

N <- 1e7 # Warning: slow
d <- data.frame(x1=rnorm(N),
                x2=rnorm(N, 0.8, 0.9),
                y=rnorm(N, 0.8, 0.2),
                z=rnorm(N, 0.2, 0.4))

v <- with(d, dataViewport(c(x1,x2),c(y, z)))

png("layer1.png", bg="transparent")
with(d, grid.points(x1,y, vp=v,default="native",pch=".",gp=gpar(col="blue")))
dev.off()
png("layer2.png", bg="transparent")
with(d, grid.points(x2,z, vp=v,default="native",pch=".",gp=gpar(col="red")))
dev.off()

library(png)
i1 <- readPNG("layer1.png", native=FALSE)
i2 <- readPNG("layer2.png", native=FALSE)

ghostize <- function(r, alpha=0.5)
  matrix(adjustcolor(rgb(r[,,1],r[,,2],r[,,3],r[,,4]), alpha.f=alpha), nrow=dim(r)[1])

grid.newpage()
grid.rect(gp=gpar(fill="white"))
grid.raster(ghostize(i1))
grid.raster(ghostize(i2))

您可以将它们添加为层,例如 ggplot2

【讨论】:

  • 谢谢巴蒂斯特!这几乎就是我在上面的原始帖子中所做的,尽管是在 matlab 中。很高兴看到你如何在 R 中做到这一点!干杯。
  • 顺便说一句,您可以使用此方法保留轴、刻度、添加网格等
【解决方案3】:

使用颜色描述的透明度功能。您可以将颜色定义为四个 2 字节字的序列:muddy &lt;- "#888888FF"。前三对设置 RGB 颜色(00 到 FF);最后一对设置透明度级别。

【讨论】:

  • 谢谢,但这样做的问题是它会独立设置每个点的 alpha。这意味着当点在单个数据集中重叠时,该区域要暗得多,这意味着整体效果的透明度较低。如果单个集合中没有点重叠,这会很好。但是,如果来自单个集合的 10 个数据点重叠并且 alpha 为 0.1,则生成的 alpha 为 1(即零透明度...)...N.B.上面的例子中有两个数据集……有意义吗?
  • 确实如此——所以我想我必须问一下你在那里实际生成的是什么:如果它是一个纯散点图,那么你会想要使重叠点变暗。如果它是分布函数的闪亮表示,那么你不应该从散点图开始。或者,只是让你的符号足够小以至于它们不会重叠!
  • 添加了一个编辑来澄清我正在绘制的数据类型......它们本身不是分布函数......
  • 这里有一些很好的建议。我会选择ggplot 一个。同时,我现在受到启发要问:是否有与 intersect 的二维模拟? (我要发布,所以不要在这里回答:-))
【解决方案4】:

AFAIK,使用 Matlab 的最佳选择是制作自己的绘图函数。不幸的是,散点图还没有透明度属性,所以你不能影响它。但是,如果您最粗略地创建一堆绘制许多小圆圈的循环,那么您可以轻松地给它们一个 alpha 值并获得一组透明的数据点。

【讨论】:

  • 我喜欢这个想法,但实践起来太慢了。此外,我基本上可以改变R中点的透明度,而不是..
猜你喜欢
  • 2016-06-25
  • 2013-10-23
  • 2021-07-03
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多