HOME > natural science Laboratory > コンピュータ・シミュレーション講座 > TIPS 集

Google API で数式とグラフを書く(TEX + Google Chart API + Google Visualization API)

文責:遠藤 理平 (2011年11月18日) カテゴリ:TIPS 集(84)

ウェブページで数式を利用する(TEX表記)

ウェブページで数式を用いた情報発信を行おうとするとき、いつも問題になるのが式の取り扱いについてです。 HTMLでは複雑な数式を表現することができないため、gifなど図としてHTMLに埋め込むことが一般的に行われます。

その際に問題となるのが「どのようにして図を作るのか」ということです。
自分はこれまで「Equation Magic」というソフトを利用しています。 このソフトの利点は、「TEX表記」で式を出力でき、かつコピーアンドペーストでベクトルデータとして扱える点です。 Illustratorなどのベクトルデータを扱えるソフトと組み合わせることで、数式のあるプレゼン資料などを簡単に作成することができます。
WEBページで利用する場合も、Equation Magicでgifに出力できるので問題は無いのですが、手間がかかることが唯一の欠点でした。
本稿で紹介するのは、HTMLソースに直接TEX表記で式を書くことで、google API が図にしてくれるという google が提供するサービスです。 ブラウザの拡張機能やインストールなどは一切必要ありません。HTMLのimgタグのsrcの特定の箇所にTEX表記で式を書くだけです。 つまり、式の gif 化が一切要らなくなるということです。

上の式が google API を利用したものです。図そのものは google のサーバ上で動的に作られ、それをユーザのブラウザにダウンロードしているという流れです。つまり、ネットに接続されていないローカル環境では、図をダウンロード使えません。 唯一の欠点は、URLの中にTEX表記を埋め込むため、URLエンコーディングが必要となる点です。 下のサンプルでは、PHPを利用してURLエンコーディングを行なっています。

<img src="http://chart.apis.google.com/chart?cht=tx&chs=1x0&chf=bg,s,FFFFFF00&chco=000000&chl=
<?php 
print urlencode("

\bar{H}_{n+2}(x) = \sqrt{\frac{2}{n+2}} x \bar{H}_{n+1}(x) \sqrt{\frac{n+1}{n+2}} \bar{H}_n(x)

");
?>
" alt=""/>

javascript などでも実現できると思います。 毎回サンプルのような HTML は書きたくないので、次のようにPHPの関数を定義します。

<?php
function WriteEquation( $tex ){
  $str = trim($tex);
  $str = str_replace("\r", "\\r", $str);
  $str = str_replace("\t", "\\t", $str);
  $str = str_replace("\n", "\\n", $str);

  $str = urlencode($str);
  print "
<img src=\"http://chart.apis.google.com/chart?cht=tx&chs=1x0&chf=bg,s,FFFFFF00&chco=000000&chl=
" . $str . "\" alt=\"$tex\"/>";
}
?>

そして、式を埋め込みたいところに

<?php WriteEquation("
\bar{H}_n(x) \equiv = \frac{1}{\sqrt{2^nn!\,\sqrt{\pi}}}\, H_n(x) \,e^{-\frac{x^2}{2}}
") ?>

と、TEX表記で式を書くだけです。これで手間が軽減されました。

【参考】
Google Chart APIを使って数式を埋め込む - Hello, world! - s21g

ウェブページでグラフを利用する(javascript)

グラフも式と同様、科学系の情報発信を行う際には欠かせない要素です。 自分はこれまで、gnuplot で描画した後に gif で出力し、HTML で利用するという手順でした。 本稿で紹介するのは、上の式と同様に google API を利用して、javascriptで動的にグラフを描画することのできるサービスです。

上の図は規格化したエルミート多項式を動的に描画しました。 グラフの上にマウスポインタを持って行くと、座標が表示されるといった具合です。 各座標 x に対して漸化式をjavascriptを用いて計算して、その結果を描画しています。 つまり、数値計算と描画を同時に行える点が魅力的です。

<script type="text/javascript" src="http://www.google.com/jsapi"></script>  
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawVisualization);

function NormalizedHermite (n, x ) {
  var y0, y1, y2;
  y0 = Math.sqrt(1.0/Math.sqrt(Math.PI)) * Math.exp(-Math.pow(x,2)/2.0);
  if( n==0 ) return (y0);
  y1 = Math.sqrt(2.0/Math.sqrt(Math.PI)) * Math.exp(-Math.pow(x,2)/2.0) * x;
  if( n==1 ) return (y1);
  for(var m = 2; m<=n; m++ ){
    y2 = Math.sqrt(2.0/m) * x * y1 - Math.sqrt((m-1)/m) * y0;
    y0 = y1;
    y1 = y2;
  }
  return (y2);
}
function round(n, x) {
  return( Math.round(x*Math.pow(10, n))/Math.pow(10, n));
}

var keta = 3;
function drawVisualization() {
  var data = new google.visualization.DataTable();
  data.addColumn('number', 'X');
  data.addColumn('number', 'n=0');
  data.addColumn('number', 'n=1');
  data.addColumn('number', 'n=2');
  data.addColumn('number', 'n=3');
  data.addColumn('number', 'n=4');
  data.addColumn('number', 'n=5');
  data.addColumn('number', 'n=6');
  data.addColumn('number', 'n=7');
  data.addColumn('number', 'n=8');
  data.addColumn('number', 'n=9');
  data.addColumn('number', 'n=10');
  var x;
  var y;
  var n_max = 500;
  var x_max = 20.0;
  data.addRows(n_max+2);
  for (var n =0; n<=n_max ; n++){
    x = -x_max/2.0 + x_max * n /n_max;
    data.addRow([round(keta, x), 
                round(keta, NormalizedHermite(0,x)), 
                round(keta, NormalizedHermite(1,x)+1), 
                round(keta, NormalizedHermite(2,x)+2),
                round(keta, NormalizedHermite(3,x)+3),
                round(keta, NormalizedHermite(4,x)+4),
                round(keta, NormalizedHermite(5,x)+5),
                round(keta, NormalizedHermite(6,x)+6),
                round(keta, NormalizedHermite(7,x)+7),
                round(keta, NormalizedHermite(8,x)+8),
                round(keta, NormalizedHermite(9,x)+9),
                round(keta, NormalizedHermite(10,x)+10)]);
  }
  var chart = new google.visualization.ScatterChart(
  document.getElementById('drow2'));
  chart.draw(data, {title: '規格化エルミート多項式',
                    width: 600, height: 700,
                    pointSize: 1,
                    vAxis: {title: "Y", minValue: 0, maxValue: 10, titleTextStyle: {color: "black"}},
                    hAxis: {title: "X", minValue: 0, maxValue: 10, titleTextStyle: {color: "black"}}}
            );
}
</script>

上のサンプルは、google APIの内「Scatter Chart」と呼ばれる散布図を利用しています。 このAPIの欠点は、今のところ科学用のグラフではないことです。 特に横軸や縦軸のメモリの付け方などの自由度が低く、思い通りのグラフに仕上がらない点です。 (例えば、x軸のメモリの刻み幅を変えられないなど) もし、gunuplot 並に指定できればかなり有用なツールとなるでしょう。

【参考】
Visualization: Scatter Chart - Google Chart Tools - Google Code



▲このページのトップNPO法人 natural science トップ

関連記事

TIPS 集







▲このページのトップNPO法人 natural science トップ