お絵描きソフトInkscape(インクスケープ)の使い方を初級レベルから上級レベルまで広く紹介しています。
情報追加のリクエストや分かりにくい点があれば下のCONTACTフォームからどうぞ。

Inkscapeで関数のグラフを描く

 このページでは、Inkscapeで関数(数学的な関数のほう、プログラミング言語で記述する関数ではなく)のグラフを描く方法を考えてみました。

 Inkscapeで、算数の問題文や論文に出てくるような関数(2次関数や三角関数など)のグラフを描くにはどうしたらよいだろうか?というはなしです。

   (参考:「数式」を描く

(2024.08.04更新)

 SVG形式として関数を記述する機能でもあればいいのですが、ありません。ペンツールなどを使って手で描くことも不可能とまでは言えないのでしょうけれど、現実的ではありません。

 Inkscapeのエクステンションに「関数のプロット」というのがあるのですが、使い方がよくわかりません。

 そこで調べてみたところ、「JSXGraph」と呼ばれるJavaScriptのライブラリがあり、JavaScriptのコードとして描きたい関数を定義すると、その関数のグラフをSVG形式で生成してくれるようなので、これを試してみようと思います。

 このソフトはオープンソースソフトウェアの1つで、自身もJavaScriptを使って書かれていますが、グラフを描きたい関数をJavaScriptのコードとして記述しておいて、その関数をJSXGraphのBoardオブジェクトのメソッドのパラメータとして入力すると、SVGで記述したパスオブジェクトを生成してくれるというものです。(もちろん他にもいろんな機能がありますが、ここでは省略します。)

 JavaScriptで書かれているので、JSXGraphはインストールしなくても使えます。簡単なHTMLファイルを作って、そこにJSXGraphのJavaScriptコードを読み込むよう指示する記述と、JSXGraphのBoardオブジェクトのcreateというメソッドに関数のコードを渡してSVGコードを生成してもらうよう指示する記述を加える程度です。

 Boardオブジェクトは生成結果のSVGコードを内部に記憶した上で、HTMLの空の要素(<div>要素)の中にそのSVGコードを埋め込んでくれます。結果としてWebページ上にグラフが表示されます。

 ここではWebページへの表示だけでなく、その生成結果のSVGコードを入手してInkscapeにインポートしたいのですが、Boardオブジェクトには内部に記憶しているSVGコードをシンプルに取り出すメソッドなどが無いようなので、JSXGraphのリファレンスマニュアルに書かれていたサンプルコードを(おまじないのつもりで)流用してきました。

 必要最小限な記述に絞って小さくしたHTMLファイルの中身は次のようになります。これをブラウザに読み込むとページ上に「表示」というボタンが表示されるので、クリックします。するとcreateメソッドに渡している3種類の関数(function1、function2、function3)をグラフ化したSVGコードを生成して、同じページにSVGコードを挿入してSVGの図形として表示するとともに、SVGのコード自体も表示します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>JSXGraphを使って関数のグラフのSVGデータを生成する</title>

    <link rel="stylesheet" type="text/css" href="https://jsxgraph.org/distrib/jsxgraph.css" />
    <script type="text/javascript" src="https://jsxgraph.org/distrib/jsxgraphcore.js"></script>

    <script type="text/javascript">
    function drawGraph() {
        var function1  = [function(x){ return 0.03*x*x*x;}, -5,5];
        var function2  = [function(x){ return 4*Math.exp(-(0.2*x*x));}, -5,5];
        var function3  = [x=>2*Math.sin(x), -5,5];

            var svg_output = document.getElementById('svg_output');
            var src_output = document.getElementById('src_output');

            svg_output.innerHTML = '';
            src_output.innerHTML = '';

            var board = JXG.JSXGraph.initBoard(
svg_output, 
                {   boundingbox: [-5, 5, 5, -5],
                axis: false,
                    showNavigation: false,
                    showCopyright: false }
    );
board.create('line', [[0,0],[1,0]], {strokeWidth:1, strokeColor:'lightgray'});
board.create('line', [[0,0],[0,1]], {strokeWidth:1, strokeColor:'lightgray'});
board.create('functiongraph', function1, {strokeColor:'blue'});
board.create('functiongraph', function2, {strokeColor:'green'});
board.create('functiongraph', function3, {strokeColor:'red'});
var txt = board.renderer.dumpToDataURI(false);
var ar = txt.split(',');
        src_output.append(decodeURIComponent(escape(atob(ar[1]))));
    }
</script>
    <style>
    #svg_output {
        border: 1px solid green;
        width: 500px; height: 500px;
    }
    #src_output {
        border: 1px solid blue;
        min-height: 2em;
    }
    </style>
</head>

<body>

<div id="frame">

<h1>JSXGraphを使って関数のグラフのSVGデータを生成する</h1>

<div class="right">
<input type="button" value="↓ 表示" id="render" onclick="drawGraph()" />
</div>
<br />
<div id="svg_output"></div>
<br />
<div id="src_output"></div>
</div>

</body>

</html>

 必要な部分だけ抜き書きしたようなHTMLファイルになっているので、これにいろいろ手を加えて、例えば任意の関数のJavaScriptコードを入力する欄を作って、任意の関数のグラフをSVG化するようにすることも出来るはずです。

 JavaScriptでは関数を記述する方法が2種類あるそうです。上の例でも「function(x) { return y; }」という形でy=f(x)を記述するケースと、「=>」を使って「x=>(xを使った計算式)」という形でy=f(x)を記述するケースを示しています。
 後者のような関数の記述のしかたを「アロー関数式」と呼ぶそうです。

 そして、このページに表示させたSVGのコード(<svg>・・・</svg>)の部分をクリップボードにでもコピーして別のSVGファイルに保存し、Inkscapeにインポートすれば、パスオブジェクトを使って描いたグラフをキャンバスに追加することができます。(参考:テンプレート機能とインポート機能

 生成されたグラフ(のパスオブジェクト)は非常に多くのセグメントをつないだものになっています。1000セグメントを超える感じです。

 これではこのあとInkscape上で編集するときにいろいろ不便なので、パス > 簡略化でノードの数を減らしてみました。

 ノード数は激減しますが、グラフの形はそんなに変わっていないように見えます。

 こうなってしまえば単なるパスオブジェクトなので、幅を変えたり色を変えたりすることは自由です。

 ちなみに上のJavaScriptのコードでは「functiongraph」というタイプを指定してグラフを描いてもらっていますが、他のタイプを指定することもJSXGraphでは可能です。詳しくは「JavaScriptでオブジェクトを描く」のほうにまとめています。ここで示した単なる線ではないいろんな座標軸を描く方法もそちらに書いてあります。

 例えば関数ではなく、「円」を描きたいときは次のように記述します。

board.create('circle', [[0,0], [1,0]]);

 こうすると円オブジェクトが生成されます。