【问题标题】:How to add contours to a density scatter plot in R?如何将等高线添加到 R 中的密度散点图?
【发布时间】:2021-07-08 07:28:38
【问题描述】:

我有一个代码可以生成这样的密度散点图(在这里找到How to add an ellipse to a scatter plot colored by density in R?):

## Data in a data.frame
x1 <- rnorm(n=1000, sd=2)
x2 <- x1*1.2 + rnorm(n=1000, 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("#FF3100", "#FF9400", "#FCFF00", 
                            "#45FE4F", "#00FEFF", "#000099"))(6)
df$col <- ifelse(df$dens >= 250, cols[1], ifelse(df$dens >= 200, cols[2], ifelse(df$dens >= 150, cols[3], ifelse(df$dens >= 100, cols[4], ifelse(df$dens >= 50, cols[5], cols[6])))))

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

我想添加与下图完全相同的轮廓(在此处找到 https://fr.mathworks.com/matlabcentral/fileexchange/8577-scatplot):

我必须在没有 ggplot2 的情况下这样做。

请问有人有意见吗?

【问题讨论】:

    标签: r plot scatter-plot


    【解决方案1】:

    这些等高线显示给定级别的数据估计密度。您可以使用MASS::kde2d() 计算密度估计值,然后使用contour() 绘制:

    biv_kde <- MASS::kde2d(x1, x2)
    contour(biv_kde, add = T)
    

    编辑:

    这是使用KernSmooth 获取彩色密度轮廓的另一种方法:

    (请注意,我在生成数据之前使用了set.seed(123)。)

    # estimate bandwidths
    h <- c(dpik(df$x1), dpik(df$x2))
    
    # obtain density estimatte
    f1 <- bkde2D(df[, 1:2], bandwidth = h, gridsize = c(200, 200))
    
    # setup vector of density levels to obtain contours for
    contour_levels <- pretty(f1$fhat, 9)
    
    # setup color palette
    crp <- colorRampPalette(rev(c("#FF3100", "#FF9400", "#FCFF00", 
                                  "#45FE4F", "#00FEFF", "#000099")))
    
    # density based colors 
    df$col <- densCols(x1, x2, bandwidth = h, colramp = crp)
    
    # plot
    plot(x2 ~ x1, data = df, pch = 20, col = col, cex = 0.5)
    contour(f1$x1, f1$x2, f1$fhat, levels = contour_levels, col = crp(9),
            lwd = 2, add = T) 
    

    【讨论】:

    • 这是一个好的开始,谢谢!但是,它并非在所有情况下都有效:如果我有这样的东西:i.imgur.com/HPNvc09.png,我会得到类似的东西:i.imgur.com/mMnqfbT.png,它与颜色不对应。这个问题能解决吗?
    • 没有数据很难判断,但我认为这与估计密度时使用的带宽有关......请注意 densCol()kde2d() 有一个带宽参数(bandwidth / @987654337 @) 确定估计的平滑度。你能在你的问题中添加一个代表吗?
    • 会不会是因为你的代码没有使用df$col?也许我应该在代码中的某个地方添加它以使轮廓线与颜色相匹配?我的真实数据看起来与df 完全一样,x 轴为一列,y 轴为另一列,颜色为第三列。通过reprex,您的意思是分享我的真实数据和我的代码以重现与我的imgur中相同的情节?不过,我会尝试使用 bandwidth 参数!
    • 对不起,我没有注意到轮廓也是彩色的!我已经编辑了我的答案并添加了另一个可以产生更平滑结果的示例。 (:
    • 这与轮廓颜色无关抱歉,我需要的是围绕i.imgur.com/GOV32zU.jpg 之类的颜色区域,我认为它不适用于我的真实数据,因为您没有使用@ 987654341@。不过,您的编辑在测试数据上看起来更好!我在我的真实数据上进行了尝试,但得到了Error in contour.default(coordPoints$x, coordPoints$y, f1$fhat, levels = contour_levels, : increasing 'x' and 'y' values expected。我按 x1 对数据进行了排序,删除了 dup 和 NA,但仍然出现此错误。我不明白为什么,因为我的真实数据真的很像测试数据。也许我应该在这里分享它们,但如何?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 2022-01-12
    相关资源
    最近更新 更多