简体   繁体   English

在 R 中随时间绘制概率密度热图

[英]Plotting Probability Density Heatmap Over Time in R

Let's say I have the output of a monte-carlo simulation of one variable over several different iterations (think millions).假设我有一个变量在几个不同的迭代中的蒙特卡罗模拟的输出(想想数百万)。 For each iteration, I have the values of the variable at each point in time (ranging from t=1 to t=365).对于每次迭代,我都有每个时间点的变量值(范围从 t=1 到 t=365)。

I would like to produce the following plot: For each point in time, t, on the x axis and for each possible value "y" in a given range, set the color of x,y to "k" where "k" is a count of how many observations are within a vicinity of distance "d" to x,y.我想制作以下图:对于x轴上的每个时间点t以及给定范围内的每个可能值“y”,将x,y的颜色设置为“k”,其中“k”是在距离 "d" 到 x,y 的附近有多少观测值的计数。

I know you can easily make density heatmaps for 1D data, but is there a good package for doing this on 2 dimensions?我知道您可以轻松地为一维数据制作密度热图,但是是否有一个很好的包可以在二维上执行此操作? Do I have to use kriging?我必须使用克里金法吗?

Edit: The data structure is currently a matrix.编辑:数据结构目前是一个矩阵。

                                     data matrix

                                      day number
             [,1]    [,2]         [,3]      [,4]       [,5]      ... [,365]
iteration    [1,]    0.000213   0.001218    0.000151   0.000108  ... 0.000101
             [2,]    0.000314   0.000281    0.000117   0.000103  ... 0.000305
             [3,]    0.000314   0.000281    0.000117   0.000103  ... 0.000305
             [4,]    0.000171   0.000155    0.000141   0.000219  ... 0.000201
              .
              .
              .
     [100000000,]    0.000141   0.000148    0.000144   0.000226  ... 0.000188

I want to, for each "day" have the pixels running vertically across that "day" to represent the probability density of the iteration's values for that day in color.我想,对于每个“天”,像素在那个“天”上垂直运行,以表示该天迭代值的概率密度。 The result should look like a heatmap.结果应该看起来像热图。

Here is one solution to what I think you are after.这是我认为您所追求的一种解决方案。

  1. Generate data.生成数据。

    myData <- mapply(rnorm, 1000, 200, mean=seq(-50,50,0.5))

This is a matrix with 1000 rows (observations) and 201 time points.这是一个包含 1000 行(观察)和 201 个时间点的矩阵。 In each time point the mean of data there shifts gradually from -50 to 50. By 0.5 each time.在每个时间点,数据的平均值从-50逐渐变化到50。每次0.5。

  1. Get densities.获取密度。

    myDensities <- apply(myData, 2, density, from=-500, to=500)

This will give you a list of densities for each column.这将为您提供每列的密度列表。 In order for them to be plottable side by side we specified the ranges (from -500 to 500) manually.为了让它们可以并排绘制,我们手动指定了范围(从 -500 到 500)。

  1. Obtain density values from the list.从列表中获取密度值。

    Ys <- sapply(myDensities, "[", "y")

This is again a list.这又是一个清单。 You need to get a matrix from that.你需要从中得到一个矩阵。

  1. Get matrix from list.从列表中获取矩阵。

    img <- do.call(cbind, Ys)

This simply combines all Ys elements by column.这只是按列组合所有Ys元素。

  1. Plot.阴谋。

    filled.contour(x=1:ncol(img), y=myDensities[[1]]$x, t(img))

I use filled.contour for that.我为此使用了filled.contour。 But you can look around for other 2-D plot functions.但是您可以四处寻找其他二维绘图功能。 I also used values obtained from the densities D[[1]]$x .我还使用了从密度D[[1]]$x获得的值。

And here is the result:结果如下:

密度

The shift from -50 to 50 is visible.从 -50 到 50 的转变是可见的。

Not sure if this can work well with millions of time points.不确定这是否适用于数百万个时间点。 But plotting million probably makes little sense since you will in any case by limited by the number of pixels.但是绘制百万可能没有什么意义,因为无论如何您都会受到像素数量的限制。 Some kind of pre-processing might be necessary.可能需要进行某种预处理。

Another way to present data over time is to create a video.随着时间的推移呈现数据的另一种方法是创建视频。

The following uses the same matrix data as Karolis:下面使用与 Karolis 相同的矩阵数据:

library(av)

myData <- mapply(rnorm, 1000, 200, mean=seq(-50,50,0.5))

# create function that includes a for loop, the output from 
# each iteration of the for loop will become one frame in
# the animation.
make_plot <- function(myData){
  
  xrange = range(myData)
  
  for(i in seq_along(myData[1,])){
    
    d <- density(myData[,i],
                 bandwidth = 45) # returns the density data
    plot(d, 
         xlim=xrange, 
         ylim=c(0, 0.003), 
         main = paste("Density, day:",i))
 
  }
}

# create video
av_capture_graphics(make_plot(myData),
                    output = "Density change over time.mp4",
                    width = 720,
                    height = 480,
                    framerate = 120)

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

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