如何简化具有数百万个数据点的晶格xyplot?

时间:2013-07-23 22:29:41

标签: r plot lattice

我有多组时间历史数据,大约500赫兹一次收集12小时。

我在日志时间范围内使用xyplot type="l"绘制了此数据,因为这种现象在很大程度上是对数衰减。

生成的图是巨大的pdf文件,需要花费很长时间来渲染和膨胀我的文档的文件大小,因为我假设正在绘制每个单独的数据点,这总是过度杀伤。这些图可以合理地再现,数量级更少。

切换到type="smooth"修复了渲染和文件大小问题,但黄土平滑显着改变了线条的形状,即使在使用黄土平滑参数进行操作之后,所以我放弃了黄土平滑作为选项在这里。

是否有一种简单的方法可以对绘图进行后处理以简化绘图,或者在绘图之前对数据进行子采样?

如果对数据进行二次采样,我认为以一种逆对数方式这样做是有益的,其中接近零的数据具有高时间频率(使用源数据中的所有500 Hz),但是时间会随着数据减少的频率而变化(甚至0.01 Hz在t = 12小时附近就足够了) - 这会在对数时间尺度上产生或多或少相等的绘图分辨率。

1 个答案:

答案 0 :(得分:1)

在尝试type="spline"并再次对其改变数据形状的程度感到不满之后,我决定采用子采样方法,在绘图之前减少数据密度。

我写的函数将沿着对数刻度进行子采样,以便"绘图分辨率"或多或少是不变的。

## log.subsample(data,time,n.per.decade)

## subsamples a time-sampled data.frame so that there are no more than
## n.per.decade samples in each decade.

## usage
## data: data.frame, the data frame object, must contain a column with
##       times
##
## time: charater, the name of the data frame column with the time
##       values
## n.per.decade: the max number of rows per decade of time

## value
## returns a data.frame object with the same columns as data,
## subsampled such that there are no more than n.per.decade rows in
## each decade of time. Any rows in data with time < 0 are dropped.

log.subsample <- function(data,time,n.per.decade){
    time.col <- grep(x=colnames(data),pattern=time)
    min.time <- min(data[,time.col])
    if(min.time < 0){
        data <- data[data[,time.col]>0,]
        min.time <- min(data[,time.col])
        droplevels(data)
    }
    max.time <- max(data[,time.col])
    stopifnot(max.time > 0)
    min.decade <- floor(log10(min.time))
    max.decade <- ceiling(log10(max.time))

    time.seq <- seq(from=min.decade, to=max.decade, by=1/n.per.decade)
    time.seq <- 10^time.seq
    for(i in 1:length(time.seq)){
        tmp <- which(data[,time.col] >= time.seq[i])[1]
        if(!is.na(tmp)){
            if(!exists("indices.to.keep")){
                indices.to.keep <- tmp
            }
            else{
                indices.to.keep <- c(indices.to.keep,tmp)
            }
        }
    }
    indices.to.keep <- unique(indices.to.keep)
    result <- data[indices.to.keep,]
    result <- droplevels(result)
    return(result)
}

这里唯一的问题是,如果有任何&#34;组&#34;在要绘制的数据中,需要在每个组上单独运行此子采样功能,然后需要构建数据框以传递到xyplot()

如果有人可以告诉我是否可以注射&#34;那将会很棒。这个子采样例程以某种方式进入xyplot()调用,这样就可以依次为每个单独的数据组调用它,无需中断数据,运行子采样例程,并在调用之前将数据重新组合在一起xyplot()