简体   繁体   English

如何使用颜色平滑处理2d热图...或从绝对值绘制密度图?

[英]How to do a 2d heatmap with color smoothing … or a density plot from absolute values?

I've done the rounds here and via google without a solution, so please help if you can. 我已经完成了这里的游戏并通过谷歌没有解决方案,所以请尽可能帮助。

I'm looking to create something like this : painSensitivityHeatMap using ggplot2 我期待创造这样的事情: painSensitivityHeatMap使用GGPLOT2

I can create something kinda similar using geom_tile, but without the smoothing between data points ... the only solution I have found requires a lot of code and data interpolation. 我可以使用geom_tile创建类似的东西,但没有数据点之间的平滑......我发现的唯一解决方案需要大量的代码和数据插值。 Not very elegant, me thinks. 我认为不是很优雅。 uglySolutionUsingTile uglySolutionUsingTile

So I'm thinking, I could coerce the density2d plots to my purposes instead by having the plot use fixed values rather than a calculated data-point density -- much in the same way that stat='identity' can be used in histograms to make them represent data values, rather than data counts. 所以我在思考,我可以通过使用固定值而不是计算的数据点密度来强制密度二维图,而不是计算数据点密度 - 就像在直方图中使用stat ='identity'一样使它们代表数据值,而不是数据计数。

So a minimal working example: 这是一个最小的工作示例:

df <- expand.grid(letters[1:5], LETTERS[1:5])
df$value <- sample(1:4, 25, replace=TRUE)

# A not so pretty, non-smooth tile plot
ggplot(df, aes(x=Var1, y=Var2, fill=value)) + geom_tile()

# A potentially beautiful density2d plot, except it fails :-(
ggplot(df, aes(x=Var1, y=Var2)) + geom_density2d(aes(color=..value..))

This took me a little while, but here is a solution for future reference 这花了我一点时间,但这是一个供将来参考的解决方案

A solution using idw from the gstat package and spsample from the sp package. 使用gstat包中的idw和sp包中的spsample的解决方案。

I've written a function which takes a dataframe, number of blocks (tiles) and a low and upper anchor for the colour scale. 我写了一个函数,它采用数据帧,块数(tile)以及颜色标度的低和高锚。

The function creates a polygon (a simple quadrant of 5x5) and from that creates a grid of that shape. 该函数创建一个多边形(一个5x5的简单象限),并从中创建该形状的网格。

In my data, the location variables are ordered factors -- therefor I unclass them into numbers (1-to-5 corresponding to the polygon-grid) and convert them to coordinates -- thus converting the tmpDF from a datafra to a spatial dataframe. 在我的数据中,位置变量是有序因子 - 因此我将它们分解为数字(1到5对应于多边形网格)并将它们转换为坐标 - 从而将tmpDF从datafra转换为空间数据帧。 Note: there are no overlapping/duplicate locations -- ie 25 observations corresponding to the 5x5 grid. 注意:没有重叠/重复位置 - 即25个对应于5x5网格的观测值。

The idw function fills in the polygon-grid (newdata) with inverse-distance weighted values ... in other words, it interpolates my data to the full polygon grid of a given number of tiles ('blocks'). idw函数用反距离加权值填充多边形网格(newdata)...换句话说,它将我的数据插入到给定数量的图块(“块”)的完整多边形网格中。

Finally I create a ggplot based on a color gradient from the colorRamps package 最后,我根据colorRamps包中的颜色渐变创建了一个ggplot

painMapLumbar <- function(tmpDF, blocks=2500, lowLimit=min(tmpDF$value), highLimit=max(tmpDF$value)) {
  # Create polygon to represent the lower back (lumbar)
  poly <- Polygon(matrix(c(0.5, 0.5,0.5, 5.5,5.5, 5.5,5.5, 0.5,0.5, 0.5), ncol=2, byrow=TRUE))

  # Create a grid of datapoints from the polygon
  polyGrid <- spsample(poly, n=blocks, type="regular") 
  # Filter out the data for the figure we want
  tmpDF <- tmpDF %>% mutate(x=unclass(x)) %>% mutate(y=unclass(y)) 
  tmpDF <- tmpDF %>% filter(y<6) # Lumbar region only
  coordinates(tmpDF) <- ~x+y
  # Interpolate the data as Inverse Distance Weighted
  invDistanceWeigthed <- as.data.frame(idw(formula = value ~ 1, locations = tmpDF, newdata = polyGrid))
  p <- ggplot(invDistanceWeigthed, aes(x=x1, y=x2, fill=var1.pred)) + geom_tile() +  scale_fill_gradientn(colours=matlab.like2(100), limits=c(lowLimit,highLimit)) 
  return(p)
}

I hope this is useful to someone ... thanks for the replies above ... they helped me move on. 我希望这对某人有用...感谢上面的回复......他们帮我继续前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM