Convolution: smoothing noisy data
1d convolution
<html>
<head>
<title>1D convolution filter</title>
<style type="text/css">
body{
font-family: sans-serif;
}
svg{
//border: 1px solid #eee;
}
.chart-line{
fill:none;
stroke-width:1px;
}
.raw{
stroke:#aaa;
}
.smoothed{
stroke:#93f;
}
.axis path {
display: none;
}
.axis line {
shape-rendering: crispEdges;
stroke: #777;
stroke-dasharray: 1,5;
}
.axis .minor line {
stroke: #eee;
stroke-dasharray: 2,2;
}
</style>
</head>
<body>
<h1>global temperature anomaly data annual</h1>
<div id='chart'></div>
<div class='key'>
</div>
</body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
var margin = {
left:30,
right:30,
top:30,
bottom:30
}
d3.csv('global.csv',function(temperatureData){
var width = 700;
var height = 500;
var kernel = normaliseKernel( [0.1, 0.2, 0.3, 0.2, 0.1] );// gaussian smoothing
var raw = temperatureData.map(function(d){
return parseFloat(d.annual_mean);
});
var smoothed = convolute(temperatureData, kernel, function(datum){
return parseFloat(datum.annual_mean);
});
var y = d3.scale.linear()
.domain( d3.extent( raw ) )
.range( [height-margin.top, margin.bottom] );
var x = d3.scale.linear()
.domain( [0, raw.length] )
.range( [margin.left, width-margin.right] );
var line = d3.svg.line()
.x(function(d,i) { return x(i); })
.y(function(d,i) { return y(d); });
var svg = d3.select('#chart').append('svg').attr('height', height).attr('width', width).append('g')
svg.append('path')
.datum(raw)
.attr("class", "chart-line raw")
.attr("d", line);
svg.append('path')
.datum(smoothed)
.attr("class", "chart-line smoothed")
.attr("d", line);
var ticks = d3.extent( raw );
ticks.push(0)
ticks = ticks.sort();
var yAxis = d3.svg.axis()
.scale(y)
.tickSize(width - (margin.left+margin.right))
.tickValues( ticks )
.orient("right");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+margin.left+",0)")
.call(yAxis);
})
function convolute(data, kernel, accessor){
var kernel_center = Math.floor(kernel.length/2);
var left_size = kernel_center;
var right_size = kernel.length - (kernel_center-1);
if(accessor == undefined){
accessor = function(datum){
return datum;
}
}
function constrain(i,range){
if(i<range[0]){
i=0;
}
if(i>range[1]){
i=range[1];
}
return i;
}
var convoluted_data = data.map(function(d,i){
var s = 0;
for(var k=0; k < kernel.length; k++){
var index = constrain( ( i + (k-kernel_center) ), [0, data.length-1] );
s += kernel[k] * accessor(data[index]);
}
return s;
});
return convoluted_data;
}
function normaliseKernel(a){
function arraySum(a){
var s = 0;
for (var i =0;i<a.length;i++){
s += a[i];
}
return s;
}
var sum_a = arraySum(a);
var scale_factor = sum_a / 1;
a = a.map(function(d){
return d / scale_factor;
})
return a;
}
</script>
</html>
"year","annual_mean"
1880,-0.31
1881,-0.22
1882,-0.28
1883,-0.3
1884,-0.33
1885,-0.32
1886,-0.29
1887,-0.35
1888,-0.28
1889,-0.18
1890,-0.4
1891,-0.29
1892,-0.33
1893,-0.34
1894,-0.35
1895,-0.27
1896,-0.19
1897,-0.16
1898,-0.3
1899,-0.19
1900,-0.11
1901,-0.18
1902,-0.28
1903,-0.32
1904,-0.36
1905,-0.27
1906,-0.22
1907,-0.42
1908,-0.36
1909,-0.37
1910,-0.36
1911,-0.37
1912,-0.34
1913,-0.34
1914,-0.17
1915,-0.11
1916,-0.31
1917,-0.39
1918,-0.35
1919,-0.22
1920,-0.22
1921,-0.16
1922,-0.27
1923,-0.23
1924,-0.24
1925,-0.19
1926,-0.04
1927,-0.17
1928,-0.15
1929,-0.29
1930,-0.11
1931,-0.04
1932,-0.1
1933,-0.22
1934,-0.1
1935,-0.15
1936,-0.07
1937,0.04
1938,0.08
1939,-0.01
1940,0.02
1941,0.08
1942,0.01
1943,0.08
1944,0.18
1945,0.05
1946,-0.07
1947,-0.01
1948,-0.05
1949,-0.07
1950,-0.17
1951,-0.05
1952,0.01
1953,0.09
1954,-0.11
1955,-0.12
1956,-0.19
1957,0.08
1958,0.08
1959,0.05
1960,-0.01
1961,0.07
1962,0.03
1963,0.07
1964,-0.21
1965,-0.12
1966,-0.03
1967,0
1968,-0.04
1969,0.08
1970,0.03
1971,-0.1
1972,0
1973,0.15
1974,-0.07
1975,-0.03
1976,-0.15
1977,0.14
1978,0.03
1979,0.1
1980,0.2
1981,0.27
1982,0.06
1983,0.27
1984,0.1
1985,0.06
1986,0.13
1987,0.28
1988,0.33
1989,0.21
1990,0.37
1991,0.36
1992,0.13
1993,0.14
1994,0.24
1995,0.4
1996,0.31
1997,0.42
1998,0.59
1999,0.34
2000,0.36
2001,0.5
2002,0.58
2003,0.57
2004,0.49
2005,0.63
2006,0.56
2007,0.59
2008,0.44
2009,0.57
2010,0.64
2011,0.52
2012,0.52