2012-08-15 21 views
7

Buscando una forma de trazar el promedio móvil/móvil en d3 sin tener que manipular los datos con anticipación. Así que quiero suavizar la línea promediando cada punto de datos con los dos después. Mi código es asíGráfico de movimiento/promedio móvil en d3.js

var data = [3, 66, 2, 76, 5, 20, 1, 3, 8, 90, 2, 5, 70]; 

var w = 20, 
    h = 80; 

var x = d3.scale.linear() 
    .domain([0, 1]) 
    .range([0, w]); 
var y = d3.scale.linear() 
    .domain([0, 100]) 
    .rangeRound([h, 0]); 

var chart = d3.select("body").append("svg") 
    .attr("class", "chart") 
    .attr("width", w * data.length -1) 
    .attr("height", h); 

var line = d3.svg.line() 
    .x(function(d,i) { return x(i); }) 
    .y(function(d) { return y(d); }) 


var movingAverageLine = d3.svg.line() 
    .x(function(d,i) { return x(i); }) 
    .y(function(d) { return y(d); }) 

chart.append("svg:path").attr("d", line(data)); 
chart.append("svg:path").attr("d", movingAverageLine(data)); 

¿Puedo especificar movingAverageLine para calcular el promedio de los siguientes puntos de datos? No puedo pensar en una forma de acceder a ellos en esa función.

He creado un ejemplo en jsfiddle. http://jsfiddle.net/tjjjohnson/XXFrg/2/#run

Respuesta

0

No está seguro de lo que entendemos por "rolling media", pero si quieres ir a tomar una línea que muestra la media de los datos, aquí es una aproximación:

chart.append("svg:line") 
    .attr("x1", x(0)) 
    .attr("x2", x(1)) 
    .attr("y1", d3.mean(data)) 
    .attr("y2", d3.mean(data)) 
    .style('stroke', 'blue') 
    .style('stroke-width', 1) 

Se puede ver la jsFiddle aquí: http://jsfiddle.net/XXFrg/3/. Espero que ayude,

+0

pregunta Editado para aclarar un poco. Al decir "rodar" me refiero al uso del promedio de varios puntos en cada día, p. promedio de tres días. Esto es para suavizar la línea. – tjjjohnson

+0

Creo que tendrías que cambiar los datos: cuando pases la matriz a una función d3, se repetirá a través de 1 elemento a la vez. ¿Alguna razón por la que no puedes simplemente crear otra matriz para aprobar? – mike

+0

no hay razón por la que no pueda modificar los datos, solo me preguntaba si había algún astuto d3 genial que lo hiciera bien – tjjjohnson

2

La siguiente función de línea debe hacer lo que quiera. Fórmula basada en http://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average.

var _movingSum; 
var movingAverageLine = d3.svg.line() 
.x(function(d,i) { return x(i); }) 
.y(function(d,i) { 
    if (i == 0) { 
     return _movingSum = 0; 
    } else { 
     _movingSum += d; 
    } 
    return y(_movingSum/i); 
}) 
.interpolate("basis"); 

8

A antes de la solución da como resultado una media móvil acumulativo.

I modified the fiddle hecha por John O'Connor para proporcionar una n-moving average pasando una función de interpolación personalizada para d3.svg.line():

movingAvg = function(n) { 
    return function (points) { 
     points = points.map(function(each, index, array) { 
      var to = index + n - 1; 
      var subSeq, sum; 
      if (to < points.length) { 
       subSeq = array.slice(index, to + 1); 
       sum = subSeq.reduce(function(a,b) { 
        return [a[0] + b[0], a[1] + b[1]]; 
       }); 
       return sum.map(function(each) { return each/n; }); 
      } 
      return undefined; 
     }); 
     points = points.filter(function(each) { return typeof each !== 'undefined' }) 
     // Note that one could re-interpolate the points 
     // to form a basis curve (I think...) 
     return points.join("L"); 
    } 
} 
var movingAverageLine = d3.svg.line() 
    .x(function(d,i) { return x(i); }) 
    .y(function(d,i) { return y(d); }) 
    .interpolate(movingAvg(6)); 
+0

Buen trabajo allí. Sin embargo, no puedo hacer que funcione con otra interpolación (como "monotone"). ¿Alguna idea sobre cómo ir con eso? – Cystack

+0

@Cystack tenga en cuenta el violín actualizado: http://jsfiddle.net/plmrry/ktLtN/ –

+1

Hola gente del futuro. aquí hay una actualización para d3 v4. por favor agradece a los respondedores. http://stackoverflow.com/questions/41386083/plot-rolling-moving-average-in-d3-js-v4/41388581#41388581 – swyx