PlotlyはJavaScriptの対話型視覚化ライブラリです。
Plotlyを使うには,<head> ... </head> の中に
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
と書き込んでおきます(あるいは上記ファイルをダウンロードして自サイトに設置し,それを上と同様に読み込みます)。
そして,グラフを入れたいところに,例えば次のような空の div を作ります。
<div id="out"></div>
その下の適当なところに,グラフを描くスクリプトを例えば次のように入れます。
<script>
Plotly.newPlot("out", [{
x: [1, 2, 3, 4, 5],
y: [1, 2, 4, 8, 16]
}], {}, {responsive: true});
</script>
すると,次のようになります。
マウスで範囲指定すると,その部分が拡大されます。軸ラベルの上でドラッグすると,グラフが平行移動します。グラフの上でダブルクリックすると,最初の状態に戻ります。グラフの上にマウスを乗せると,グラフの右上にコントロール(ボタン類)が現れます。この🏠ボタンをクリックすると,最初の状態に戻ります。
グラフの種類などはオプションで指定できます。グラフの幅はブラウザの幅になります。Plotly.newPlot() の第4引数に {responsive: true} を指定すると,レスポンシブ(ブラウザの幅に追従するデザイン)になります。小さなスマホでは幅が狭く感じられると思いますので,画面を横にしてみてください。幅と高さを明示的に設定するには,例えば次のようにします。
<div id="out" style="width: 640px; height: 480px"></div>
データの欠測値は null または NaN で表します。
背景を灰色,グリッドを白にし,ゼロ線を特別扱いしない設定:
<script>
Plotly.newPlot("out", [{
x: [1, 2, 3, 4, 5],
y: [1, 2, 4, 8, 16]
}], {
plot_bgcolor: "#DDD",
xaxis: {gridcolor: "white", zeroline: false},
yaxis: {gridcolor: "white", zeroline: false}
}, {responsive: true});
</script>
データは,上の例ではHTMLファイルに直接書き込みましたが,JSONやCSVなどの形式で別にしておくほうが楽です。例えば上の例で,データを
[{
"x": [1, 2, 3, 4, 5],
"y": [1, 2, 4, 8, 16]
}]
のようなJSONファイルにしておけば,JavaScript部分は
fetch('test.json')
.then(response => response.json())
.then(data => {
Plotly.newPlot("out", data);
});
のようにできます。
データは同じサーバに置いておきます。JavaScriptのセキュリティ制約のため,別のサーバに置いたデータを読むことはできません。この制約をなくすためには,HTTPヘッダに Access-Control-Allow-Origin '*' を付けます(→ CORS)。GitHub(GitHub Pagesも含め)はこれが付いていますので,オープンデータとして公開したいデータはGitHubに置いておくのが楽です。Apacheで運用しているサイトなら,httpd.conf の例えば <Directory /> と </Directory> の中に Header set Access-Control-Allow-Origin '*' と書いておきます。
CSVファイルはJavaScriptでパースして配列にする必要があります。
Pythonのところで,平均身長の推移をPythonのPlotlyで描きました。同じデータをJavaScriptだけで描いてみましょう。
このデータは height.csv というCSVファイルに収められています。欠測値は空文字列で表しています。これを読んでグラフにするために,このファイルのheadの中には,次のように書き込んであります:
<script>
function plot(data) {
let year = [], m15 = [], m16 = [], m17 = [];
for (const row of data.split("\n")) {
const r = row.split(',');
if (r.length == 27) {
year.push(r[0]);
m15.push(r[11]);
m16.push(r[12]);
m17.push(r[13]);
}
}
Plotly.newPlot("out1", [
{name: "男17歳", x: year, y: m17, type: "scatter", mode: "lines+markers"},
{name: "男16歳", x: year, y: m16, type: "scatter", mode: "lines+markers"},
{name: "男15歳", x: year, y: m15, type: "scatter", mode: "lines+markers"}
],
{xaxis: {title: {text: "年度"}},
yaxis: {title: {text: "身長"}},
legend: {x: 0.8, y: 0}},
{responsive: true});
}
window.addEventListener('DOMContentLoaded', function() {
fetch('../python/data/height.csv')
.then(response => response.text())
.then(data => plot(data));
});
</script>
下の <div id="out1"></div> の中に出力されます:
CSVの仕様はけっこう難しく,JavaScriptにもCSVをパースするライブラリがいくつもあるのですが,ここでは単に改行とコンマで切り分け,中身を文字列としてそのままpushしています。この部分で数値に変換することもできますが,Number() で変換すると,空文字列が 0 に変換されてしまいます。parseFloat() なら NaN になり,Plotlyで欠測値と解釈されます。
Last modified: