> ## Content Index
> Fetch the complete content index at: https://oroup.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Unevenly spaced time series analysis
- URL: https://oroup.com/blog/2016/05/unevenly-spaced-time-series-analysis/
- Published: 2016-05-01T18:12:13.000Z
- Updated: 2026-07-05T22:58:56.000Z
- Description: A number of years ago I bought a Withings connected scale. It’s great. You get on every morning, it logs your weight and uploads it to the internet where it can be analyzed. Recently, I decided to use the Withing…
- Author: Oliver Roup
- Tags: Code, #wp, #wp-post, #Import 2026-07-05 22:27

A number of years ago I bought a [Withings connected scale](http://www.withings.com/us/en/products/smart-body-analyzer?ref=oroup.com). It’s great. You get on every morning, it logs your weight and uploads it to the internet where it can be analyzed.

Recently, I decided to use the [Withing API](http://oauth.withings.com/api?ref=oroup.com) to build a plot that I could include on my homepage to keep an eye on my weight. Something every weight-watcher knows though is your weight fluctuates and so it’s great to keep an average. Unfortunately, unevenly spaced time series do not interact well with simple moving averages, so I found [this paper](https://oroup.com/blog/content/files/eckner-com/papers/unevenly%5Fspaced%5Ftime%5Fseries%5Fanalysis.pdf) and converted [the code](http://eckner.com/papers/ts%5Falg.zip?ref=oroup.com) into javascript:

```

var tau = 1000 * 60 * 60 * 24 * 3.5 // 1/2 week
var i = 0
var left = 0
var t_left_new, roll_area, left_area, width, weight, y2
var avg_data = [[json_data[0][0], json_data[0][1]]]
roll_area = left_area = json_data[0][1] * tau
for (i = 1; i < json_data.length; i++) {
  roll_area += (json_data[i][1] + json_data[i - 1][1]) / 2 * (json_data[i][0] - json_data[i - 1][0])
  roll_area = roll_area - left_area
  t_left_new = json_data[i][0] - tau
  while (json_data[left][0] < t_left_new) {
    roll_area = roll_area - (json_data[left][1] + json_data[left + 1][1]) / 2 * (json_data[left + 1][0] - json_data[left][0])
    left++
  }
  width = json_data[left][0] - t_left_new
  if ((left === 0) || (width === 0)) {
    left_area = width * json_data[0][1]
  } else {
    weight = width / (json_data[left][0] - json_data[left - 1][0])
    y2 = json_data[left - 1][1] * weight + json_data[left][1] * (1 - weight)
    left_area = width * (y2 + json_data[left][1]) / 2
  }
  roll_area = roll_area + left_area
  avg_data[i] = [json_data[i][0], roll_area / tau]
}

```

The algorithm expects data in a variable called json\_data. It’s an array of arrays, each of which is a timestamp and data pair. (This is the form that Highcharts expects.) The key factor is tau, the length of the time window over which you’re averaging. I have it set to a week here which I think is about right for looking at human weight. (3.5 days works quite well too.)

The results are here:
  
  
The [code in context](https://oroup.com/pub/weight/graph.js?ref=oroup.com) and a [cleaner running example](https://oroup.com/pub/weight/?ref=oroup.com) are both available. You can also see the [raw data](https://oroup.com/pub/weight/data/?ref=oroup.com) I use to fuel the graph.