開発環境
- OS X El Capitan - Apple (OS)
- Emacs (Text Editor)
- JavaScript (プログラミング言語)
- D3.js (JavaScript Library)
- kjs-math-statistics
- Safari(Web browser)
- JavaScript 第6版 (David Flanagan(著)、村上 列(翻訳)、オライリージャパン)(参考書籍)
- インタラクティブ・データビジュアライゼーション(Scott Murray(著)、長尾 高弘(翻訳)、オライリージャパン)(参考書籍)
Pythonからはじめる数学入門 (Amit Saha (著)、黒川 利明 (翻訳)、オライリージャパン)の3章(データを統計量で記述する)、3.9(プログラミングチャレンジ)、問題3-3(他のCSVデータでの実験)をJavaScript(とD3.js)で取り組んでみる。(バージョンアップで D3.js にいろいろ変更点があったみたい。)
問題3-3(他のCSVデータでの実験)
CSVファイル(WWDI | Population, total - Japan)
コード(Emacs)
HTML5
<div id="graphs0"></div>
<br>
値: <span style="color:blue">----------</span>
平均値: <span style="color:green">----------</span>
中央値: <span style="color:red">----------</span>
<div id="output0"></div>
<input id="nums_data" type="file">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<script src="sample3.js"></script>
JavaScript
(function () {
'use strict';
var width = 600,
height = 400,
padding = 50,
padding_left = 120,
div_graphs = document.querySelector('#graphs0'),
div_output = document.querySelector('#output0'),
input_file = document.querySelector('#nums_data'),
readCsv,
display,
drawGraph;
Array.prototype.sum = function () {
var s = 0;
this.forEach(function (num) {
s += num;
});
return s;
};
Array.prototype.mean = function () {
var s = this.sum(),
n = this.length;
return s / n;
};
Array.prototype.median = function () {
var numbers = this.slice(),
len = numbers.length,
i1,
i2,
median;
numbers.sort();
if (len % 2 === 0) {
i1 = len / 2 - 1;
i2 = i1 + 1;
median = (numbers[i1] + numbers[i2]) / 2;
} else {
i1 = (len + 1) / 2 - 1;
median = numbers[i1];
}
return median;
};
Array.prototype.modes = function () {
var obj = {},
count,
num,
max = 0,
modes = [];
this.forEach(function (num) {
if (obj[num] === undefined) {
obj[num] = 1;
if (max === 0) {
max = 1;
}
} else {
count = obj[num] + 1;
obj[num] = count;
if (count > max) {
max = count;
}
}
});
for (num in obj) {
if (obj[num] === max) {
modes.push(parseInt(num, 10));
}
}
return modes;
};
Array.prototype.differences = function () {
var mean = this.mean(),
diff;
diff = this.map(function (num) {
return num - mean;
});
return diff;
};
Array.prototype.variance = function () {
var diff = this.differences(),
squared_diff,
len = this.length;
squared_diff = diff.map(function (x) {
return Math.pow(x, 2);
});
return squared_diff.sum() / len;
};
Array.prototype.standard_deviation = function () {
var variance = this.variance(),
std_deviation = Math.sqrt(variance);
return std_deviation;
};
Array.prototype.zip = function (a) {
var len1 = this.length,
len2 = a.length,
ary = [],
i;
if (len2 < len1) {
len1 = len2;
}
for (i = 0; i < len1; i += 1) {
ary[i] = [this[i], a[i]];
}
return ary;
};
readCsv = function () {
var file = input_file.files[0],
reader;
reader = new FileReader()
reader.readAsText(file);
reader.onload = function () {
var text = reader.result,
years_and_population = [];
years_and_population = text.split('\n')
.slice(1, -1)
.map(function (row) {
var cols = row.split(','),
year = parseInt(cols[0].split('-')[0], 10),
pop = parseFloat(cols[1]);
return [year, pop];
});
years_and_population.reverse();
display(years_and_population);
};
reader.onerror = function (error) {
throw error;
};
};
display = function (points) {
var years,
population,
pop_len,
diff = [],
years_and_diff,
mean,
median,
modes,
variance,
std_dev,
i;
years = points.map(function (point) {
return point[0];
});
population = points.map(function (point) {
return point[1];
});
pop_len = population.length;
for (i = 0; i < pop_len - 1; i += 1) {
diff[i] = population[i + 1] - population[i];
}
mean = diff.mean();
median = diff.median();
modes = diff.modes();
variance = diff.variance();
std_dev = diff.standard_deviation();
years_and_diff = years.slice(1).zip(diff);
div_output.innerHTML =
'平均値: ' + mean + '<br>' +
'中央値: ' + median + '<br>' +
'最頻値: ' + modes.join(', ') + '<br>' +
'分散: ' + variance + '<br>' +
'標準偏差: ' + std_dev + '<br>';
div_graphs.innerHTML =
'<div id="graph0"></div>' +
'<div id="graph1"></div>';
drawGraph('graph0', points,
{
x_label:'年',
y_label:'人口',
});
drawGraph('graph1', years_and_diff,
{
x_label:'年',
y_label:'差異',
mean: mean,
median: median
});
};
drawGraph = function (id, points, obj) {
var n = points.length,
xs,
ys,
svg,
xscale,
xaxis,
yscale,
yaxis;
xs = points.map(function (elem) {
return elem[0];
});
ys = points.map(function (elem) {
return elem[1];
});
xscale = d3.scaleLinear()
.domain([d3.min(xs), d3.max(xs)])
.range([padding_left, width - padding]);
xaxis = d3.axisBottom().scale(xscale);
yscale = d3.scaleLinear()
.domain([d3.min(ys), d3.max(ys)])
.range([height - padding, padding]);
yaxis = d3.axisLeft().scale(yscale);
svg = d3.select('#' + id)
.append('svg')
.attr('width', width)
.attr('height', height);
svg.selectAll('line')
.data(points.slice(0, n - 1))
.enter()
.append('line')
.attr('x1', function (d, i) {
return xscale(d[0]);
})
.attr('y1', function (d, i) {
return yscale(d[1]);
})
.attr('x2', function (d, i) {
return xscale(points[i + 1][0]);
})
.attr('y2', function (d, i) {
return yscale(points[i + 1][1]);
})
.attr('stroke', function (d, i) {
return 'blue';
});
svg.append('g')
.attr('transform', 'translate(0, ' + (height - padding) + ')')
.call(xaxis);
svg.append('g')
.attr('transform', 'translate(' + padding_left + ', 0)')
.call(yaxis);
if (obj.x_label) {
svg.append('text')
.attr('x', padding_left + (width - padding_left - padding) / 2)
.attr('y', height - padding / 4)
.attr('text-anchor', 'middle')
.text(obj.x_label);
}
if (obj.y_label) {
svg.append('text')
.attr('x', padding_left / 4)
.attr('y', height / 2)
.attr('text-anchor', 'middle')
.text(obj.y_label);
}
if (obj.mean) {
svg.append('line')
.attr('x1', xscale(d3.min(xs)))
.attr('y1', yscale(obj.mean))
.attr('x2', xscale(d3.max(xs)))
.attr('y2', yscale(obj.mean))
.attr('stroke', 'green');
}
if (obj.median) {
svg.append('line')
.attr('x1', xscale(d3.min(xs)))
.attr('y1', yscale(obj.median))
.attr('x2', xscale(d3.max(xs)))
.attr('y2', yscale(obj.median))
.attr('stroke', 'red');
}
};
input_file.onchange = readCsv;
}());
値: ---------- 平均値: ---------- 中央値: ----------
0 コメント:
コメントを投稿