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: