texファイルにgnuplotコマンドを埋め込む


# はじめに
LaTeXの文書にグラフやデータのプロットを載せるとき，どのような方法を使っていますか？ MatlabやPythonのMatplotlibを使ったり，グラフ用紙に手書するなどして，最終的に画像化したものを`\includegraphics{}`するのがおそらく一般的な方法かと思います。

ところで，こんな経験はありませんか？
- 画像化したあとで，ミスに気付きやり直し
- 画像をどこに保存したか分からなくなった
- 画像のファイル名を指定するのが面倒
- 何のグラフか分からなくなった

これらを解決し得る一つの方法として，**gnuplottexパッケージ**とその使い方を紹介したいと思います。





# gnuplottexパッケージの何が嬉しいか
gnuplottexパッケージを使うと，**texファイルの中にgnuplotのコマンドを書く**ことができます。タイプセットと同時にgnuplotが自動的に呼び出され，きれいなグラフを挿入してくれます。


#### gnuplotのコマンドを一元管理できる

本文の編集中に，シームレスにグラフの編集ができます。gnuplotファイルを用意する必要がありません。何のグラフだったか忘れても，近くの本文を読めば思い出せます。


#### 作業が減る
自動化されているので，グラフを画像化して保存し，文書に取り込むという一連の作業もなくなります。ミスを見つけた時も，簡単に修正することができます。


#### グラフに数式を挿入できる
軸や凡例に数式を書くことができます。複雑な関数を書くのも，単位を書くのも簡単です。
<!-- 凡例に関数を書くのも，軸に$T$とか$\beta$とか書くのも，単位を書くのも簡単です。-->








# 環境
- Ubuntu 22.04 (<- Windows 11 + WSL2)
  - TeX Live 2023
  - gnuplot 5.4 patchlevel 2

にて確認。
<!-- Linux環境を用意し，TeX Liveとgnuplotを導入します。-->
:::note info
<!-- Windows環境で同じことを試しましたが，上手くいきませんでした。-->
Windows環境では，あとで出てくるshell escapeが有効にならず，上手く行きませんでした。
Mac OSや他のLinuxは使ってないので分かりません。
ご自分の環境でも試してみてください。
:::






# 必要な設定
gnuplotのターミナルには様々な種類があり，gnuplottexパッケージでも複数に対応しています。ここでは，tikzというターミナルを指定することにします[^a]。

gnuplottexパッケージ自体はTeX Liveに含まれていますが，ターミナルにtikzを指定するには**gnuplot-lua-tikzパッケージ**を準備する必要があります。これが今回やるべき唯一の設定です。

[^a]:[gnuplottexの公式ドキュメント][doc]に"Probably offers the best output terminal at the moment"とあるので。

<details><summary>gnuplot-lua-tikzパッケージについて</summary>

このパッケージは，gnuplotのターミナルとしてtikzを指定するために必要です。gnuplot-lua-tikzはTeX Liveに含まれていないので，スタイルファイル等を手動で配置します。

tikz以外のターミナル（latexやcairolatexなど）を指定すればgnuplot-lua-tikz無しでgnuplottexを使うことができるはずなので，それでもいいです。私は試してません。
</details>

# gnuplot-lua-tikzパッケージの準備
<!--適切なディレクトリにスタイルファイルを準備しましょう。-->
:::note warn
具体的なディレクトリやコマンドは，お使いの環境に合わせて適宜読み替えてください。
<!-- TeX Liveのインストール先，お使いの環境に合わせて -->
:::

まずはスタイルファイルを置く場所を探します。ターミナルで
```
$ kpsewhich -var-value=TEXMFLOCAL
```
を実行します。TeX Liveのインストール先がデフォルトのままなら，`/usr/local/texlive/texmf-local/`が表示されると思います。全ユーザーに適用したくなければ，上で`TEXMFLOCAL`の代わりに`TEXMFHOME`とします。これらの場所は，TeX Liveを新しいバージョンにしても変更を受けず，ユーザーが手動でスタイルファイルを置くのに適しています。
<details><!-- <summary>TeX Live ガイド</summary>-->

[TeX Live ガイド](https://tug.org/texlive/doc/texlive-ja/texlive-ja.pdf "https://tug.org/")より引用。
> TEXMFLOCAL このツリーは、システム管理者が全ユーザに適用するためにマクロやフォントなどを追加または更新して配置するためのものです。
> TEXMFHOME このツリーは、一般のユーザが独自に追加または更新したいマクロやフォントを配置するためのものです。この変数の参照先は、使用するユーザごとに固有のディレクトリです。
</details>

次に，表示されたディレクトリに移動し，さらにその下の`tex/latex/`まで移動します。もしなければ作ってください[^1]。その下にroot権限で`gnuplot-lua-tikz`というディレクトリを作り，移動します[^2]。その後，root権限でgnuplotを起動します。
[^1]:root権限が必要です。つまり`sudo mkdir`です。
[^2]:TEXMFLOCAL以下のどのディレクトリに置くべきかは特に決まっていないはずです。私は，TeX Liveに含まれるgnuplottexなどのスタイルファイルの場所を参考にしました。
```
$ sudo gnuplot
```
gnuplotが起動出来たら，次のコマンドを実行します。
```gnuplot:gnuplot
set terminal tikz createstyle
exit
```
これにより，スタイルファイルを含む4つのファイルが生成されます。
<details><summary>確認方法</summary>

`ls`コマンドを打てば4つのファイルが生成されていることが確認できます。

```
$ ls
gnuplot-lua-tikz-common.tex  gnuplot-lua-tikz.sty  gnuplot-lua-tikz.tex  t-gnuplot-lua-tikz.tex
```
</details>


最後に，配置したスタイルファイルを認識してもらうために，次のコマンドでls-Rファイルを更新します。

```
$ sudo mktexlsr
```

<details><summary>確認方法</summary>

ホームディレクトリなどの適当なディレクトリに移動して次のコマンドを実行し，先ほど作成したスタイルファイルのパスが表示されれば成功です。
```
$ kpsewhich gnuplot-lua-tikz.sty
/usr/local/texlive/texmf-local/tex/latex/gnuplot-lua-tikz/gnuplot-lua-tikz.sty
```
</details>

<details><summary>ls-Rファイルとは</summary>

[TeX Wiki LaTeX 「入門/各種パッケージの利用」](https://texwiki.texjp.org/?LaTeX%E5%85%A5%E9%96%80%2F%E5%90%84%E7%A8%AE%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E5%88%A9%E7%94%A8 "TeX Wiki")より引用（2023年12月22日）。


> LaTeX がファイルを読み込むときは TeX のディレクトリの中から目当てのファイルを探しますが，ファイルを探すのはそれなりの時間がかかります。 そこで考え出されたのが「あらかじめファイルの一覧表を作っておき，ファイルを探すときにはそれを参照する」という仕組みで，この一覧表 (ls-R) を作るコマンドが mktexlsr です。

</details>

**これで設定は完了です。**




# 使い方


実際に使ってみましょう。読み込むべきパッケージなど，詳しくはサンプルコードを見てください。`gnuplot`環境の中にgnuplotのコマンドを書くことができます。オプションとして`terminal=tikz`を指定します。そのあとの`terminaloptions`は必須ではありませんが，グラフのサイズやフォントを変更することができます。

:::note info
`gnuplot`環境中ではコメントアウトもgnuplotと同様に`#`です。
また，$\alpha$と書きたい場合はバックスラッシュを重ねて`$\\alpha$`とします。
:::

### サンプルコード1
適当なディレクトリに次のファイルを置いてください。エンジンはLuaLaTeXを使うことを前提に書いています。


```latex:example1.tex
\documentclass{ltjsarticle}   % お好きなドキュメントクラスでよいと思います。
\usepackage{luatexja}         % LuaLaTeXで日本語を使うのに必要です。
\usepackage{shellesc}         % shell escapeするのに必要です。
\usepackage{gnuplottex}       % 今回の主人公。
\usepackage{tikz}             % gnuplot-lua-tikzパッケージはtikzを使う前提なので。
\usepackage{gnuplot-lua-tikz} % 手動で配置したgnuplot-lua-tikzパッケージです。
\usepackage{siunitx}          % 本文中やグラフの軸に単位を書くために使います。
\usepackage{float}            % 図を出力する位置を自分で指定するため。

\begin{document}
$\sin x$と，その近似式をプロットしてみましょう。
\begin{figure}[H]
  \centering
  \begin{gnuplot}[terminal=tikz, terminaloptions={plotsize 9cm, 6cm}]
    set samples 1000
    set xrange [-5:5]
    set yrange [-3:3]
    set grid
    set xlabel "$x$"
    set ylabel "$y$"
    plot \
    sin(x) title "$\\sin x$", \
    x title "$x$", \
    x - x**3 / 6 title "$x - x^3/3!$", \
    x - x**3 / 6 + x**5 / 120 title "$x - x^3/3! + x^5/5!$"
  \end{gnuplot}
\end{figure}
\end{document}
```


実行は次のコマンドで行います。`-shell-escape`オプションを忘れないでください。

<details><summary>shell escapeとは何か</summary>

[shellesc]: https://texwiki.texjp.org/?%E5%A4%96%E9%83%A8%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E5%AE%9F%E8%A1%8C "TeX Wiki"

[TeX Wiki 「外部コマンドの実行」][shellesc]に詳しく書かれています。

デフォルトの設定では，外部コマンドの実行が制限された状態（restricted shell escape）になっています。`-shell-escape`オプションを付けることで，gnuplotを含む任意の外部コマンドの実行が可能になります。

ところで，[TeX Wiki 「外部コマンドの実行」][shellesc]をみる限りでは，restricted shell escapeの状態でも，`texmf.cnf`ファイルを編集して，安全なプログラムとして登録しておけば，外部コマンドとして実行できるはずです。gnuplotで試してみたのですが，どうも上手くいきません。[gnuplottexの公式ドキュメント][doc]には，
> Shell escape is available in the web2c TEX compiler, it allows the execution of shell code during the compilation of a TEX document. It’s disabled by default, **you’ll have to edit your configuration files or** give the -shell-escape option to latex.

とあるので，色々調べていじっていれば，いつかは成功するかもしれません。

</details>

```
$ lualatex -shell-escape example1.tex
```


下の画像のようなpdfが得られたでしょうか？



![example1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641621/7e0322d2-f895-8cbb-ee67-2b15aded4170.png)


### サンプルコード2
こちらは参考までに。

<details><summary>サンプルコードを表示する</summary>

```latex:example2.tex
\documentclass{ltjsarticle}   % お好きなドキュメントクラスでよいと思います。
\usepackage{luatexja}         % LuaLaTeXで日本語を使うのに必要です。
\usepackage{shellesc}         % shell escapeするのに必要です。
\usepackage{gnuplottex}       % 今回の主人公。
\usepackage{tikz}             % gnuplot-lua-tikzパッケージはtikzを使う前提なので。
\usepackage{gnuplot-lua-tikz} % 手動で配置したgnuplot-lua-tikzパッケージです。
\usepackage{siunitx}          % 本文中やグラフの軸に単位を書くために使います。
\usepackage{float}            % 図を出力する位置を自分で指定するため。

\begin{document}
ここに本文を書きます。ここに本文を書きます。ここに本文を書きます。ここに本文を書きます。
ここに本文を書きます。ここに本文を書きます。ここに本文を書きます。ここに本文を書きます。

実験データをプロットしてみましょう。図\ref{fig:example2}のようになりました。
\begin{figure}[H]
  \centering
  \begin{gnuplot}[terminal=tikz, terminaloptions={plotsize 9cm, 6cm}]
    set samples 1000
    set log x
    set xtics 10
    set ytics 30
    set mytics 3
    set xrange [10:1e6]
    set yrange [-120:150]
    set grid
    set xlabel "周波数$f \\, \\unit{\\per\\hertz}$"
    set ylabel "位相差$\\theta \\, \\unit{\\per\\deg}$"
    
    R = 2206
    C = 105e-9
    L = 889.8e-6
    r = 22.2
    plot \
    (180 / pi) * atan(R * (2 * pi * x * L / (r**2 + (2 * pi * x * L)**2) - 2 * pi * x * C) / (r * R / (r**2 + (2 * pi * x * L)**2) + 1)) title "理論曲線（$r$を考慮）", \
    (180 / pi) * atan(R * (1 / (2 * pi * x * L) - 2 * pi * x * C)) title "理論曲線（$r$を無視）", \
    'exp1.dat' using 1:4:5 with yerrorbars title "測定値"
  \end{gnuplot}
  \caption{微分回路に正弦波を入力したときの電圧の位相差。縦軸に位相差を取り，横軸に周波数の対数を取った。理論曲線は，インダクタンスの内部抵抗$r$を考慮した場合と無視した場合の2つを書き込んだ。}
  \label{fig:example2}
\end{figure}
数式を埋め込むのも簡単です。
\end{document}
```

</details>

![example2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641621/b9795c88-2abc-ca18-65e7-cef892bb5cb6.png)



是非レポートなどで使ってみてください！




# 参考
- [TeX Wiki](https://texwiki.texjp.org/ "TeX Wiki")：日本語のLaTeX関連の情報が集まっています。
- [gnuplottexの公式ドキュメント][doc]：ここに書いてある情報がおそらく一番正しい。

他にも参考になる記事を2つ挙げておきます。1つ目の記事では，TikZのexternalライブラリを使ってコンパイルにかかる時間を短縮する方法について説明されています。

https://qiita.com/satl/items/0c11c8808b43f806ee21

https://qiita.com/kou-JP/items/309dfd3729f602cd0042


[doc]: https://ftp.yz.yamagata-u.ac.jp/pub/CTAN/macros/latex/contrib/gnuplottex/gnuplottex.pdf "gnuplottex"