tomgp
9/30/2013 - 9:26 PM

Convolution: smoothing noisy data

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