ページが長いので「しおり」の仕組みを用意してみました。
「しおり用」と書かれた所をクリックしてからブックマークに入れると、
それはページの先頭ではなく、その箇所へのブックマークになります。
(03/03 2006)
前回の報告 (11/09 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
また報告が 2 ヶ月ほど開きましたが、今回もいくつかの更新が入っています。
出力形式として、tek.trm に sixel 出力形式というものが追加されました。 これは、DEC の古い端末でサポートされていたグラフィック形式らしいですが、 よくは知りません。
また、emf 出力形式に対して、 「情報やメモ (11/28 2013)」 で報告したいくつかの問題に対する修正が追加されました。 ただし、fill pattern に対しては、 それが作る EMF ファイルの fill pattern は LibreOffice ではうまく表示されない、という問題があるようです (もしかすると LibreOffice 側の問題 ?)。
また、今回は history に関する修正もだいぶ行われて、 シェルの history と同様に、N 番目のコマンドを再実行したり、 「set historysize」が廃止されて、 それを拡張した「set history」が新設されています。
また、plot title に関して、 個別に {no}enhanced をつけれるようにしたこと、 notitle と title が完全に同じオプションを許すようにしたこと、 などの修正もありました。 この後者は、plot ... title "hoge" と書いたものを、 「title」の部分だけ「notitle」としてもちゃんと動くように、 ということのようです。
mcsplines という smooth オプションが追加されましたが、 これは「区分的単調 3 次スプライン」(piecewise monotonic cubic splines) というもので、元のデータ点の単調性、凸性を保持するもののようです。
そして、新しい描画スタイルとして、 「with parallelaxes」というものが追加されました。 これは parallel axes plot、parallel coordinates plot などと呼ばれるもののようで、 日本語では「平行座標描画」などと言われるようです。 統計分野で利用されるもののようですが、 これは x, y の 2 軸 (または x, y, z の 3 軸) を垂直に置くのではなく、 多次元のデータ軸を平面に平行に並べ、 データの組 (データファイルの 1 行のデータ) を各軸に取って それを隣り合う軸毎に線分で結んだものです。 データ行分の独立した折れ線ができます。 サンプルは、例えば以下を参照してください。
個人的にはあまり見たことがありませんが、 3 次元以上のデータの相関を見るにはよさそうですね。 ただ、なんとなくですが、 データ軸の並べ方などを試行錯誤する必要がありそうな気がします。
(cf. 「情報やメモ (01/29 2014)」, 「情報やメモ (07/22 2014)」, 「情報やメモ (07/22 2014)」, 「情報やメモ (05/03 2016)」)
Gnuplot Q&A 掲示板 (2673 番の記事) で、 emf terminal に関する問題点がいくつか指摘されました。 それらについて報告します。
もともとは、2 ちゃんねるの掲示板「gnuplot を使おう。その 3」 (アドレスは リンクリスト 参照) で報告されていたものをまとめたもののようです。 報告されている問題点はいくつかあり、まとめると、
のような感じです。 まず、1 つ目の pointtype 6 の円と 2 つ目の arrow の軸ですが、 以下のようなスクリプトで問題が起こります。
set term emf
set output 'temp.emf'
set arrow from -8,14 rto 5,-5 head size 5,20 empty lt 1 lw 6
set arrow from -8, 9 rto 5,-5 head size 5,20 filled lt 1 lw 6
plot x w p lt 1 lw 6 pt 4 ps 2 , x+3 w p lt 1 lw 6 pt 6 ps 2
これらは、いくつかの箇所で lw を見ずに 固定した線幅を設定していたことによる問題でした。 pointtype 6 だけでなく 7 の円 (7 は塗り潰しの円) も影響を受けます。 これらは多分以下の差分で修正できます。
3 つ目の set multiplot title の問題は、 以下のようなスクリプトで問題が起こります。
set term emf
set output 'temp1.emf'
set multiplot title 'hoge'
plot x
unset multiplot
set output 'temp2.emf'
set multiplot title 'hoge'
plot x
unset multiplot
4 つ目の pattern fill の問題は、test コマンドで確認できます。
EMF ではパターンでの塗り潰しが少し面倒くさいこともあり (情報も少ない)、 これまで実装されてこなかったためのものです。 今までは色の濃さでごまかしていたようですが、 他の出力形式のパターンもだいたい同じ形に揃いましたので、 EMF もそれに合わせるべきだろうと思います。 以下の差分でそれを実装してみました。 全部一から作ったわけではなく、 例えばビットパターンなどは win terminal (src/win/wgraph.c) から拝借しています。
なお、現在の CVS 版は、xtics のデフォルトの形式の変更 (%h) に伴い、 × (積) を表す Unicode 文字列が一つ src/util.c に入っていて、 それが Shift_JIS 環境の場合に問題を起こしてしまいますので、 Shift_JIS 環境の VC++ などでコンパイルする場合には、 以下のパッチが必要になると思います。
Gnuplot Q&A 掲示板で情報を紹介してくださった ryo-naka さん、 どうもありがとうございました。 一応いずれのパッチも、すでに本家の方に送ってありますが、 採用されるかどうかはまだわかりません。
(cf. 「情報やメモ (12/27 2013)」, 「情報やメモ (07/18 2014)」, 「情報やメモ (07/22 2014)」, 「情報やメモ (05/03 2016)」)
前回の報告 (09/09 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
少し前回の報告から間が開きましたので、 色々変更が入っていますが、あまり大きなものはないと思います。 ただ、見た目に影響を与える変更もなくはありませんので、 従来と出力が変わった、という場合もあるとは思います。
例えば、今回軸の刻みのデフォルトの書式が、 従来の %g から、新設された %h に変更されました。 %h は、%g が指数表記をする場合には「e+XX」のように表記するのに代わり、 x10^{XX} のように表記するもののようです。 確かにそちらの方が良く使われるような気もしますし、 実際そのように表現されるように自前で設定されていた場合も多いと思います。
クリッピング処理も、ルーチンの改良、ルールの変更などの他に、 オブジェクトに対するクリッピングオプションも新設されています。
その他には、極座標モードの自動縮尺の際の rmax の評価や、 RGB 色に関する変更、lt, lc 回りの修正なども入っています。 enhanced モードをサポートする出力形式では、 それがデフォルトになったのも少し便利かもしれません。
また、今回 16bit DOS 時代の古いコードが削除され、それとともに unixpc という M68010 ベースの AT&T 3b1, AT&T 7300 Unix PC 用の古いドライバも破棄されました。 Wikipedia を見ると、1980 年代位のもののようで、 Microsoft もまだ MS-DOS 3.X 位の時代です。 画面出力もかなり原始的な時代のもののようですが、 コアなファンはかなりいるらしく インターネットにはまだかなり情報があります。 そんなコンピュータで gnuplot がどのようなグラフを出力していたのか 若干興味はありますが、さすがにそういう情報は見あたりません。 ドライバのソースを見ると、 720x300 ビットマップを仮定していて、 線種も 4 種類をサポートしているようですので、 もしかすると意外に綺麗なグラフ (dumb よりはずっとましなもの) を書いていたのかもしれません。
(cf. 「情報やメモ (12/27 2013)」)
gnuplot-4.6.4 がリリースされています。 配布物に含まれる NEWS には、以下のように書かれています。
マイナーバージョンアップではだいたいそうですが、 見てわかる通り、大きな変更はありません。 CVS 版で既に色々取り入れられている機能はありますが、 それらは次のメジャーバージョンアップ (4.8.0) で採用されるのだろうと思います。
前回の報告 (08/11 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
多分一番目につくのはゲームデモでしょう。 いずれも矢印キーなどをホットキーとして使うもので、 nibbles は snake (古くからの Unix ユーザならわかるでしょうか) の変種、 xixit はテトリスの変種のようです。 このようなことが gnuplot でできてしまいますが、 それに合わせてマウス処理に関する修正が行われています。
新設オプションの「reset session」も、 通常の reset よりも便利な場合が多いと思います。
もう一つの大きな変更が gnuplot の新しいコマンドラインオプションである -c です。 gnuplot のコマンドラインでスクリプトとして指定すると、 それは通常 load コマンドで読み込んだ状態になるのですが、 それを load でなく call に変えて、 その後のオプションを gnuplot ではなく call したスクリプトへのオプション とみなすものです。 これにより、今までは間接的にしか呼べなかった call 用のスクリプトを 直接 gnuplot から呼べるようになりますし、 gnuplot スクリプトの先頭に
#!/usr/local/gnuplot -cのようなものを入れて実行権限を与えることで、 オプションを使用する gnuplot スクリプト (call スクリプト) を 直接実行することができるようになります (ただし、私はまだ試していません)。
なお、この「gnuplot -c」の機能は、山本さんの 「gnuplot の精義」(第 2 版) の 6.4 節に書かれていることの示唆から実現したものです。 実は、最近の gnuplot の更新には、 他にもいくつかこの本に関連した修正、追加などがあります。 山本さん、どうもありがとうございました。
(cf. 「情報やメモ (11/09 2013)」)
2 ちゃんねるの掲示板「gnuplot を使おう。その 3」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
FreeBSD のパッケージから gnuplot+ がなくなった、 という記事がありました (152)。
確かに最新の ports リストからはなくなっているようです。 私が使っている FreeBSD-8.2 にはまだありますから、 少し前の ports を使って入れる、という手はあるかもしれません。
http://www.freshports.org/math/gnuplot+/ を見ると、今年の 2 月頃になくなっているようです。削除理由は
This package is obsolete. The author does not recommend to use it.とありますが、 確かに 3.7 系列の gnuplot に戻るよりも 今の 4.6 系列の gnuplot を使う方が賢明だと思います。 マニュアルによれば gnuplot+ ができる機能は以下の通りですが、 現在の gnuplot でも多くが対応できています:
現在は epslatex, cairolatex, lua, mp terminal などで、 グラフと文字部分を分離した出力を生成し、 文字部分は LaTeX に渡すような仕組みがありますから、 ほぼそれで代用できるでしょう。
または psfrag package を使って、Postscript 内の文字を LaTeX の文字に LaTeX 側で置きかえる、という手もあります。
現在は、postscript, x11, png (gd ライブラリ) では問題なく日本語が使えます。 ただし、pbm や epson, hp のプリンタに関する日本語化は 多分対応していません。
既に組込まれています (configure 時に選択)
その機能はありませんが、環境変数 GNUHELP に ヘルプファイルを指定できますので、 gnuplot 実行中に切り替えるのは無理ですが、 起動時にヘルプファイルを切り替えることなら可能です。
qt terminal はどういいのか、という記事がありました (155)。
多分、その前の 153 の記事のサンプルスクリプトで、 対話型 terminal への復帰に set term qt としてあったための質問だと思います。
もちろん、153 の記事のサンプルは、「set term qt」でなくて 「set term wxt」でも「set term win」でも「set term x11」 でもいいわけですが、 qt terminal のいいところは、と言われると微妙ですね。 クロスプラットフォーム、という点では wxt とそう変わりません。 qt terminal が wxt terminal よりも優位な点、というのも思いつきません。 グラフウィンドウのメニューが日本語化されていることくらいでしょうか。
当然ですが、KDE 環境のように Qt がすでに使える環境にあり、 wxWidgets を使うにはインストールしないといけない、 という場合には優位だろうとは思います。
最近の gnuplot では set term png で直接 png が出力できると知った、 といった記事がありました (156)。
この記事の意図とは多分違いますが、png terminal について少し書きます。 実は、これまで「png terminal」という形で利用できた (できる) terminal は以下の 3 種類のドライバのものがありました (あります)。
最後の cairo 由来のものは「pngcairo terminal」という名前で、 正確には「png terminal」ではないのですが、 gd.trm が有効でなくて cairo.trm が有効な場合、 「set term png」で「pngcario terminal」が起動するようになっています。 だから、png terminal だと思って使っているものが、 実は pngcairo terminal である、という可能性はあります。 それは set term を実行した際に表示される「Terminal type set to ...」 の部分を見れば確認できます。
e-100 より小さい値をプロットすると 1 位の大きい値になってしまうのですが、 という質問がありました (159)。
CPU のバグでは、といった返信もありましたが、 これは実際に貼り付けてあったデータを見ると
0.000000000000E+00となっていて、0 以外のデータの部分の 'E' が抜けていますので、 多分勘違いだと思います。 実際、- の前に E をおぎなうと正しく小さい値が表示されます。 E-201 くらいだとまだ倍精度の制限にはぶつかりませんから 特に問題なく表示されます。
0.000000000000E+00
0.000000000000E+00
0.435473392210-201
0.156895824551-183
....
4 列のデータから、中心の x 座標、y 座標、半径、「透過度」を読み取って 円を描きたい (with circles) という質問がありました (162)。
その記事によれば「透過度」というのは fillstyle の solid に指定する値のことで、「solid 0.15」を「solid variable」 に変えて列データから読み取りたい、ということのようです。
163 番の記事でも指摘されていますが、 その「透過度」(というよりも「塗り潰し密度」という方が多分適切) は variable のようにしてデータファイルから読み取ることはできません。 ソースを改良すれば可能かもしれませんが、ちょっと難しそうな気がします。
また、少し試してみたのですが、solid の後ろに 「0.9-0.8」のような数式を書いても正しく 0.1 と認識されるようですが、 「f(x)」のような関数を書くとエラーになるようです。 もし関数が使えるなら、plot for で 1 行ずつ書かせればなんとかなるかと思ったのですが それもだめなようです。
となると、gnuplot 内部からやることはあきらめて、 私なら awk などでやるでしょうか。 例えばデータ file.dat が
1.0 1.0 0.7 0.5のように、中心の x, y 座標、半径、塗り潰し密度、となっているとして、 以下のような awk スクリプト mk1.awk を作って gnuplot スクリプトを吐かせます (もちろん awk 内部で gnuplot へのパイプを作って、 直接 gnuplot へ命令を渡すことも可能です):
1.0 2.0 0.7 0.8
2.0 2.0 0.7 1.0
2.0 1.0 0.7 0.2
BEGIN {
print "set term wxt";
print "set size square";
print "set xrange [0:3]";
print "set yrange [0:3]";
}{
if (NR==1) printf "plot 'file.dat'";
else printf ",\\\n ''";
printf " using 1:2:3 every ::%d::%d", NR-1, NR-1;
printf " notitle with circles lc rgb 'blue'";
printf " fs transparent solid %s", $NF;
} END { print "" }
これを使って、
% awk -f mk1.awk file1.dat > mk1.gp
のようにして gnuplot スクリプト mk1.gp を作成し、
% gnuplot -persist mk1.gp
のようにするわけです。
シェルスクリプトのヒアドキュメントを使えば その中で全部の作業を行うことができますし、 上に書いたように awk スクリプト内部だけで行うこともできます。
gnuplot コマンドを行末に \ を置いて複数行書いた場合、 コマンドヒストリも複数行に分かれて保存されてしまうが、 それを 1 行にできないか、という質問がありました (166)。
確かにそうなっている方がいいかなという気もします。 ただ、かなり長いコマンド行になってしまうと、 編集もやや面倒かもしれません。 簡単にするには、外部でフィルタで変換することでしょう。 多分 perl や ruby などでやると楽なんだと思いますが、 例えば awk でやるなら (ヒストリファイルを .gnuplot_history とします):
% awk '{s=$0; while(s ~ /\\$/) { sub(/\\$/, "", s);
getline; s=s " " $0 } print s}'
.gnuplot_history > tmpf
% mv tmpf .gnuplot_history
のようにすればいいわけです。
長いですが、シェルスクリプトにしておけば楽でしょう。
しかも、いっそそのシェルスクリプトを gnuplot の初期化ファイル
(~/.gnuplot) 内で ! を使って gnuplot の起動時に実行しておくようにすれば
意識する必要がなくなります。
ただし、これは gnuplot のの再起動時に有効なだけで、 現在実行中の gnuplot では有効にはなりません。 そこまでやろうとすると、やはりソースを改変しないといけないでしょう。 有益な気もしますので、時間があったら少し考えてみたいと思います。
(cf. 「情報やメモ (07/18 2014)」)
前回の報告 (06/29 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回の重要な変更は以下の通りです。
デフォルトでは、非常に短い arrow は、 矢先も小さくするようになっているそうですが、 size fixed を指定すると小さくしなくなります。
arrowstyle で filled を使用している場合用ですが、 これを指定すると、矢先の周囲の線を描かなくなります。 実は、2 点を結ぶ arrow は、この矢先の周囲の線の幅の分だけ、 矢先が終点から少しずれてしまうそうです。 この矢先の境界線を描かないようにすると、 矢先の先端が丁度終点に一致するようになります。
これにより、一つの plot title 内で、 複数の columnhead(N) を使用するようにできるようになるようです (例えば「plot 'file' using 1:2 title columnhead(1) . ' vs ' . columnhead(2)」のように)
「複素誤差関数」などを実装する libcerf なるものがあるようです (cf. http://apps.jcns.fz-juelich.de/doku/sc/libcerf)。
libcerf は complex.h が利用可能 (C99) な環境用のライブラリですが、 無理矢理やれば少し古い環境 (例えば Solaris 9) でも インストールできなくはありません (cf. 「Unix に関するメモ等 (07/19 2013)」)。 ただし、その場合は gnuplot のコード (src/libcerf.c) も修正が必要です。
従来、set xtics の level は 0 (major), 1 (minor) の 2 つしかありませんでしが、 これがより大きな数字レベルも指定できるようになりました。 現在使用可能なレベルは多分 5 くらいまでです。 2 以上のレベルは明示的な指定しかできませんが、 minor tics (level 1) とは違い、ラベルをつけることが可能です。
tgif terminal の点のサイズは、 他の出力形式に比べてやや大き目だったようです (何で見つけたのか忘れました)。 他の出力形式に合わせてやや小さくしました (ついでにバグも修正してあります)。
これまでは tgif terminal では、 arrow は tgif の命令に直していましたが、 それだとグラフ上の矢の見た目が他の出力形式と変わってしまいますし、 矢の見た目や矢の形の調整機能は、「tgif の矢」よりも「gnuplot の矢」 の方がずっと上なので、 それを、線分の描画で実現する「gnuplot の矢」に変えました。
その代わり、生成される obj ファイルでは 矢が一つの命令で実現されるのではなく、 複数の折れ線 (多角形) で描かれることになってしまいましたので、 やや善し悪しですが、多分 tgif の矢の方がありがたい、 と思う方は少ないと思います。
また、機能の追加などとは違いますが、 マニュアルの「binary matrix」の部分に一つ修正が入りました。 これは実はかなり長く存在した問題でした。 それについて少し説明します。
これまで binary matrix のマニュアルには 以下のように書かれていました:
=========== よって、非一様な matrix データの構造は以下のようになります: <N+1> <y0> <y1> <y2> ... <yN> <x0> <z0,0> <z0,1> <z0,2> ... <z0,N> <x1> <z1,0> <z1,1> <z1,2> ... <z1,N> : : : : ... : これらは以下のような 3 つの数字の組に変換されます: <x0> <y0> <z0,0> <x0> <y1> <z0,1> <x0> <y2> <z0,2> : : : <x0> <yN> <z0,N> <x1> <y0> <z1,0> <x1> <y1> <z1,1> : : : ===========ところが、実際にこのようなデータを描画すると、 この x 座標と y 座標が逆の形で出力されていました。 バグだと思いそれを修正する (x と y を入れかえる) コードを送ったこともあるのですが、 影響が大きいせいか採用されませんでした。 それがこの度、逆に現実の現象に合った形にドキュメントを修正する形で ようやく「バグが修正され」ました。 現在は、上のドキュメントの前半は以下のようになっています:
=========== よって、非一様な matrix データの構造は以下のようになります: <N+1> <x0> <x1> <x2> ... <xN> <y0> <z0,0> <z0,1> <z0,2> ... <z0,N> <y1> <z1,0> <z1,1> <z1,2> ... <z1,N> : : : : ... : ===========この問題は、山本さんの 「gnuplot の精義」 でも指摘されていました (「3.4.3 マトリックスバイナリー」)。 ようやく修正されたことになります。
(cf. 「情報やメモ (09/09 2013)」)
前回の報告 (06/03 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
前回同様、fit に関する修正がかなり入っているようです。
また、上の修正にある「"文字列"[x:y] の x,y に実数が」 というのは、もちろんこの x, y は整数しか意味を持たないのですが、 その x, y として列データから取ってきた値を使えるようにするためだそうです。 もちろん、その実数の整数部分を利用するようになっています。
実は最近、gnuplot-4.6 対応になった山本さんの 「gnuplot の精義」 の第 2 版が出版されましたが、 それを読んで気がついたところなどを本家に報告して、 それが修正されたものも上に含まれています。 例えば、
などがそれです。また、上には書いてありませんが、 マニュアルの every の項目に「: で終わる書き方は不可」 という文言を追加したりもしています。 every は、デフォルトでいい部分は空欄にして 「:3::2」のような指定が可能なのですが、「:」で終わっていると それに続くオプションを解析した上でエラーになるので、 少しわかりにくいエラーメッセージが表示されてしまいます (私は初めて知りました)。 残念ながら、それを許すよう修正するのは原理的に難しそうなので、 そのための説明をマニュアルに追加したわけです。
「every で負の値」というのも上と少し関連した話なのですが、例えば
plot 'data' using 3:2 every pp::ps::pe with points ps 2のようなものが書かれたスクリプトを、gnuplot で
gnuplot -persist -e 'pp=2; ps=3; pe=100' file.gpのように、表示する点のサンプリング間隔、開始点、終了点を 変えながら実行している場合、 それぞれの値をデフォルトの値にしたいときは、 間隔や開始点は 1 や 0 を指定すればデフォルトになるのですが、 終了点のデフォルト、すなわち最後の点の番号は、 データに依存してしまって簡単に設定できません。 そこで、簡単に
gnuplot -persist -e 'pp=-1; ps=-1; pe=-1' file.gpのようにすれば (間隔や開始点も含めて) デフォルトに戻せるように、としてみたわけです。
「show/unset datafile {commentschars...}」の話はバグの修正です。 例えば gnuplot 4.6 では「show datafile」とすると commentschars の設定も表示されるのですが、 「show datafile commentschars」だと出ません (マニュアルにはある)。 また、マニュアルに書かれている「unset commentschars」(これ自身間違い) も、「unset datafile commentschars」も効かず、 他の missing や separator などのオプションも一緒にデフォルトにしてしまう 「unset datafile」しか使えなくなっていました。 現在の CVS 版では「show datafile commentschars」 「unset datafile commentschars」が使えるようになっています。 missing や separator なども同様に show, unset が個別に使えるようになっています。
(cf. 「情報やメモ (08/11 2013)」)
最近「自分で作成した gnuplot スクリプトでオプションをつけて実行したい」 という話をあるところで見ました。
Unix では、シェルスクリプトに実行許可属性を与えて、 1 行目に「#!」から始まる行をつけることで、 それをコマンドのように使えるようになります。 この話は、これを利用したもののようで、 例えば gnuplot の call 用のスクリプト (名前は file.gp とします):
#!/usr/local/bin/gnuplot
plot sin(x)
pause -1 "Hit ENTER key."
if ( "$#" < 2 ) exit
set term $0
set output "$1"
replot
set out
のようなものに実行許可属性を与えて、
% ./file.gp 'png' 'file.png'のように実行したい、ということのようです。
もちろん、現在の gnuplot にコマンドラインから与えることができるのは 「load」コマンドで実行できるスクリプトだけなので、 このような「call」コマンド用のスクリプトをこのように実行しても うまくいきません。実際には、
% /usr/local/bin/gnuplot ./file.gp 'png' 'file.png'が行われるだけなので、gnuplot は 'png' や 'file.png' も gnuplot スクリプトだと認識してしまいます。
しかし、ソースを改造すれば gnuplot にそのようなことさせることも できなくはありません。 実際そのようなパッチを書いてみたのですが、 ふと気がついて、どうせ Unix ならば他の方法もあるのでは、 と考えてみたら、以下の 2 つの方法を思いつきました。
これは、私がいつもよくやる手で、file.gp に代わるシェルスクリプト (ここでは csh script とします) file.csh を以下のように書けば、 上に書いたことが容易に実現できます:
#!/bin/csh -f
set viewonly = 0
if ( $#argv < 2 ) set viewonly = 1
gnuplot <<EOF
plot sin(x)
pause mouse "Push mouse RIGHT button."
if ( $viewonly ) exit
set term $1
set output "$2"
replot
set out
EOF
引数の個数チェックは、シェルスクリプト側で行い、
それを viewonly という変数を介して gnuplot で処理しています。
また、シェルスクリプトへの引数 $1, $2 は、
直接ヒアドキュメント内にそう書けばそれがそのまま展開されますので、
普通の文字列として利用できます
(シェルスクリプトでは $0, $1 ではなく $1, $2)。
なお、gnuplot にヒアドキュメントでスクリプトを流すと、 それが標準入力からの入力となるので、 そのスクリプト内で標準入力を見る「pause -1」が使えません。 よって、上では「pause mouse」に置き換えています。
これは、gnuplot スクリプト側では、直接 gnuplot を呼び出すのではなく、 この中間スクリプト (プログラム) を呼び出しておいて、 その中間スクリプト (プログラム) 側で gnuplot を実行し、 与えられたオプション等は gnuplot が認識する形でその gnuplot に渡す、 という方法です。
中間プログラムは、シェルスクリプトでも、perl スクリプトでも、 C のプログラムでも、何でもいいでしょう。 中間プログラムが gnuplot を呼ぶときには、 実際に call を使う形式で呼び出す方法もあるでしょうし、 -e オプションを利用して、 内部変数を設定するコマンドをスクリプトの前に書く、 という方法もあるでしょう。 以下に、call を使って gnuplot を呼び出す中間 csh スクリプト (gpexp.csh) の一例を紹介します:
#!/bin/csh -f
set gp = /usr/local/bin/gnuplot
if ( $#argv < 1 ) exit
set s = ""
while ( $#argv > 0 )
set s = "$s '$argv[1]'"
shift
end
$gp -e "call $s"
これが呼び出されるときは、
このスクリプト内部では、
最初の引数 ($1=$argv[1]) は対象となる gnuplot スクリプトで、
それに続く引数は、gnuplot スクリプトに与えたオプションなので、
基本的には引数全体 ($argv) の頭に call をつけた文をほぼ
gnuplot -e "call $argv"のようにすればいいだけです。 しかし、call スクリプト自身は引用符で囲まなければいけませんし、 また call スクリプトの引数も、ドキュメントに書かれている通り、 引用符で囲まないと動作が保証されませんので、 それらを一々引用符で囲む作業を行っているのが while から end までの部分です。 そして、実際はそうやって作った文字列 s を call に渡す、 という文字列を gnuplot -e で実行しているだけです。
なお、このスクリプトに実行許可属性を与えて、 /usr/local/bin/gpexp.csh としたとしても、 これがシェルスクリプトなので、これを使用する gnuplot スクリプト側で
#!/usr/local/bin/gpexp.csh
...
のようにして使うことはできません。
これは、/usr/bin/env を利用して、
#!/usr/bin/env /usr/local/bin/gpexp.csh
...
のようにして使います。
上に書いた file.gp も、その先頭行をこれに変えて、
実行許可属性を与えれば、
% ./file.gp 'png' 'file.png'のようにして使えるようになります。
前回の報告 (04/30 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
一応前回の報告から 1 ヶ月くらいしか経っていないのですが、 今回はかなり変更などが入りました。 大きな改良は以下のあたりでしょうか。
Gnuplot Q&A 掲示板 (2653 番の記事) で報告があった、 emf terminal の test 出力のフォントの問題についても修正が採用されています。
いずれも、ほぼ想像がつくもの、 マニュアルを見ればだいたいわかるものでしょうから、 今回は具体例は省略したいと思います (実は面倒くさいだけ ^^;)。
河野@ロスアラモス研 さんが立ち上げている 「Gnuplot - not so Frequently Asked Questions -」 (http://t16web.lanl.gov/Kawano/gnuplot/) というサイトにお世話になった方も多いのではないかと思いますが、 最近そのサイトがアクセスできなくなっているようです。 以下にその情報があります。
出版されるのであればそれはそれでうれしいですが、サイトがないのは残念です。 そのため、上にも書いてありますが、現在はミラーがいくつかあるようです。
このサイトは日本語版だけでなく英語版があるせいもありますが、 外国でそういうことが話題になること、 および次々とミラーができていることが、 河野さんのサイトの重要性を物語っているように思います。
前回の報告 (04/02 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回は、fit 関係の修正がだいぶ入りました。 あまり fit は使わないので詳しくはよくわかりませんが、 環境変数だったものが set fit などで指定できるようになり、 gnuplot スクリプトで閉じた処理が行いやすいように なっているのではないかと思います。
また、時間の原点が、gnuplot 独自の「2000 年元旦からの秒数」から、 Unix 標準の「1970 年元旦からの秒数」に変更されました。 標準的なものになったので歓迎すべきことだと思いますが、 もしかするとこれまでの gnuplot スクリプトを 修正しないといけない場合もあるかもしれません。
set datafile separator では、これまでは 1 文字指定しかできなかったのが、 "*|" (区切りは '*' または '|') のような指定ができるようになりました。 これもある種のデータに関しては前処理が少し不要になるような 便利な機能なのかもしれません。
(cf. 「情報やメモ (06/03 2013)」)
gnuplot-4.6.3 がリリースされています。 配布物に含まれる NEWS には、以下のように書かれています。
見てわかる通り、今回は MS-Windows 用の修正が主です。 4.6.1, 4.6.2 用の MS-Windows 版バイナリは結局リリースされませんでしたが、 今回の 4.6.3 は最初から MS-Windows 版バイナリ (gp463-win32.zip) も、インストーラ形式 (gp463-win32-setup.exe) のものも、 ソースの公開と同時にリリースされています。
ところで、「スペースレイズコンソール」というのは、 コンソール版の gnuplot.exe に関する修正 (実装) のようです。 これをコマンドプロンプトから起動した場合、 グラフをプロットさせるとまずは wxt terminal や win terminal のグラフウィンドウが前面に出てコマンドプロンプト画面を隠しますが、 その状態からコンソール入力に戻るには、 今まではグラフウィンドウをマウスで閉じるか、 コマンドプロンプトをマウスで前面に出す必要がありました。 それが、スペースキー一発でコマンドプロンプトを前面に出し、 コマンド入力ができるようになるようになったのですが、 それが「スペースレイズコンソール」らしいです。
なお、マニュアルは 4.6.2 と 4.6.3 では変更がありませんので、 今回は 4.6.3 用のマニュアルの訳は行いません。 もうしわけありませんが、必要ならば 4.6.2 用のもので代用してください。
報告が遅れましたが、gnuplot-4.6.2 がリリースされています。 配布物に含まれる NEWS には、以下のように書かれています。
最近の CVS 版に入った機能などもいくつか追加されているようです。 ところで、gnuplot-4.6.0 はリリース後に MS-Windows 版バイナリや、 MS-Windows 用インストーラなどもリリースされたのですが、 gnuplot-4.6.1 のものはついに出ませんでした (もしかしたら気がついていなかっただけかも)。 4.6.2 用のものは、まだ公式ページには「not yet」と書かれていますが、 テスト版が http://www.gnuplot.info/development/binaries/ に置かれているようです。 そのうちに正式にリリースされるだろうと思います。
前回の報告 (01/26 2013)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
いくつか補足をします。
(cf. 「情報やメモ (04/30 2013)」)
先日、「情報やメモ (01/22 2013)」 に、xtics の目盛りラベル文字列をユーザ定義文字列値関数とできれば、 とか書きましたが、良く考えてみたら目盛りラベルも、目盛り位置も、 今の set for の機能を使えばかなり容易に カスタマイズできるんでした。 こんな具合です:
s(x) = sprintf("%.1f=%d+%.1f",x,floor(x),x-floor(x)) # 目盛りラベルの文字列値関数
p(x) = x - 0.3*sin(0.5*pi*x) # 目盛り位置の関数
set xrange [0:5]
unset xtics
set for [i=0:5] xtics ( s(p(i)) p(i) )
plot x
なお、この手の話は、すでに 4 年以上前にしていました (^^; (「情報やメモ (09/09 2008)」 「情報やメモ (09/11 2008)」 参照)
前回の報告 (12/21 2012)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
bind で文字列値変数を受けつけるように、というのは、
STRING = "(なんらかの gnuplot コマンド)"とできるようにした、ということのようです。 確かに、複雑なコマンド列を bind したい場合には便利かもしれません。
bind (キー) STRING
(cf. 「情報やメモ (04/02 2013)」)
x11 や wxt terminal で、グラフウィンドウ上で 'h' を打つと、 そのグラフウィンドウ上で利用できるマウス機能、 キーボード機能の一覧が表示されますが、 その一覧 (ヘルプ) は日本語化されていません。 時間がとれたら、日本語表示が可能かどうか検討したいと思いますが、 とりあえず、以下にその訳をあげておきます。
マウス (<B1> = 左、<B2> = 中、 <B3> = 右) | |
---|---|
<B1> 2 回 | `clipboardformat` を用いてクリップボードに座標を出力 (キーの '3', '4' を参照) |
<B2> | `mouseformat` (キーの '1', '2' を参照) を用いてグラフに付箋付け、 `set mouse labels` が ON ならラベル描画 |
<Ctrl-B2> | `set mouse labels` が ON ならカーソルに近いラベルの削除 |
<B3> | ズーム範囲のマーク (2D 描画と maps のみ) |
<B1-Motion> | 視方向の変更 (回転)。軸のみの回転には <ctrl> を併用。 |
<B2-Motion> | 視方向の変更 (伸縮)。軸のみの伸縮には <ctrl> を併用。 |
<Shift-B2-Motion> | 垂直移動 -- xy 平面の変更 |
<wheel-up> | 上スクロール (Y の増加方向へ) |
<wheel-down> | 下スクロール |
<shift-wheel-up> | 左スクロール (X の減少方向へ) |
<shift-wheel-down> | 右スクロール |
<control-wheel-up> | グラフの中心方向へズームイン |
<control-wheel-down> | ズームアウト |
<shift-control-wheel-up> | X 軸のみズームイン |
<shift-control-wheel-down> | X 軸のみズームアウト |
キー | |
Space | gnuplot 対話ウィンドウを上に |
q | 描画ウィンドウを閉じる |
a | 自動縮尺 (set autoscale keepfix; replot) |
b | 境界描画の ON/OFF |
e | replot |
g | 格子線 (grid) の ON/OFF |
h | help (これ) |
l | 対数軸の ON/OFF (plot では y 軸、splots では z と cb 軸) |
L | カーソルが一番近い軸への対数軸の ON/OFF |
m | マウスモードの ON/OFF |
r | 十字線 (ruler) の ON/OFF |
1 | ひとつ前の mouseformat に |
2 | ひとつ次の mouseformat に |
3 | ひとつ前の clipboardformat に |
4 | ひとつ次の clipboardformat に |
5 | 十字線原点からの動径表示 |
6 | 対話ウィンドウへの冗長表示 |
7 | ratio を巡回的に変更 |
n | 次のズーム履歴へ移動 |
p | 前のズーム履歴へ移動 |
u | ズーム解除 |
Right | 右回転 (splot のみ)、<shift> で速く回転 |
Up | 上回転 (splot のみ)、<shift> で速く回転 |
Left | 左回転 (splot のみ)、<shift> で速く回転 |
Down | 下回転 (splot のみ)、<shift> で速く回転 |
Escape | 選択中のズーム領域の解除 |
文章の間違いらしきものも見つけましたので後で報告したいと思いますが、 普段これらの機能はほとんど使っていなかったので、 今回これらを試してみたら結構面白かったです。 特にマウスホイールによるスクロールは、2D だけでなく splot でも有効なので、実行してみるとちょっと不思議な感じがします。 また、キーの '5' (キーの 'r' の後にやる) もこんな機能があるとは知りませんでした。 グラフ上で座標を確認したい人には便利かもしれませんね。
2 ちゃんねるの掲示板「gnuplot を使おう。その 3」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
「情報やメモ (08/23 2012)」 にも書いた logscale の切り替えの話題ですが (86,88-94)、 元の質問者が詳細な情報を書いたところ、 bind で if を使ったトグルスイッチ風の割り当てを行うサンプルが紹介され、 それで解決したようです (95-96)。
bind に複雑な式を割り当てるのはなかなか高度な技ですね。 gnuplot の付属のマニュアルにも、 同じようなトグルスイッチ風の少し複雑な bind の例として、 以下のようなものが書いてあります:
bind "ctrl-r" "v=v+1;if(v%2)set term x11 noraise; else set term x11 raise"対数軸の切り替えについては、「Gnuplot in Action」 (「gnuplot に関する文献等」を参照) の .gnuplot (gnuplot の初期設定ファイル) のサンプルの中 (Chapter 12. Macros, scripting, and batch operations) に、 丁度 95 番の記事の例に似たようなものが載っています:
is_log_x = 0;この本では、変数名を見てわかるように、x 軸、y 軸の対数軸の切り替えを 別々に行うためにこのようなものを書いているようです。 なお、95 番の記事は上のような replot ではなく、 直接 plot 命令が書いてありましたが、 このように replot を使う方が汎用性は高くなると思います。
bind 'x' "if(is_log_x) is_log_x = 0; unset logsc x; replot; \
else is_log_x = 1; set logsc x; replot
x 座標が 80, 90, 100 などのときに x 軸の目盛りラベルを指数表記にしたとき、 その指数部分を 101 と固定して、 「8.0x101, 9.0x101, 10x101」 となるようにすることはできるか、 set format x "%l2.1lx10^%L" ではうまくいかず 最後のものが 1.0x102 となってしまう、 という質問がありました (110)。
これに対して、10x101 という書き方は 指数表記にする意味はないのでは、 軸名の横に「x 10」のように書いて 「using ($1/10):2」で x 座標を実際には 1/10 にしてラベルをごまかしたら、 という回答がありましたが、 元記事の方はデータではなく、関数描画なのだそうです。
指数表記というよりも 10 で割った数を軸の見出しにしたいなら、 「(x 10)」のように軸に書く方が確かに普通だと思います。 データを 1/10 にするやり方は、もちろん関数描画でも行えます。 「plot [8:10] f(x*10) title "f(x)"」のようにするだけです。 そうすれば x 座標は 8 から 10 まで動きますが、 関数には 80 から 100 までの値が代入されることになります。
なお、昔から考えているのですが、 現在の gnuplot では文字列値関数が定義できますから、 軸の目盛りラベルの文字列もユーザ定義文字列値関数とできれば、 もっと目盛りラベルの自由度が上がるような気がしています。 set format との共存などがちょっと難しそうですが、 明示的な set xtics などがだいぶ楽になるだろうと思いますので、 実現できればなぁと思っています (誰かやりませんか ?)。
また、マニュアルでは %l, %L は「現在の軸の底に基づく」 となっているのですが、 その「現在の軸の底」を変更できるのは対数軸の場合だけで、 線形軸では底は 10 しか使えないようになっています。 これを、線形軸でも任意の底が使えるように修正が可能か (例えば 50x1003 や 1.2x27 などが可能になる)、 後で考えてみたいと思います。
0 から 20 までの、10000 個のデータが 1 列 (10000 行) 並んでいるデータがあるが、 それの 5 幅刻みのヒストグラムを書きたいが、 gnuplot でできないか、それとも別な方法で数を数えるしかないか、 という質問がありました (117)。
これに対して、直接ヒストグラムを書くのは無理、 基本的にグラフ描画ツールだから、 といった意見がありましたが、 元記事の方はうまく探したみたいで、 「smooth frequency」(gnuplot 4.0 以降) を利用した ヒストグラムを描くスクリプトを上げています (123)。
gnuplot に付属する smooth.dem にもサンプルがありますが、 smooth という本来データを補間するための機能の中に、 gnuplot-4.0 から smooth frequency や smooth cumulative (4.4.0 以降) などの簡単な統計的なグラフを書くためのオプションが追加されています。 これを利用するとヒストグラムはそれなりに書くことができます。 smooth frequency は、x 座標が同じデータ点を一つに集約して、 それらの y 座標の合計を y 座標とするデータにまとめます。 例えば、
1 2のようなデータの場合、smooth frequency は、
2 3
1 4
3 5
2 6
1 6にしてくれるわけです。
2 9
3 5
よって、例えば 0 以上 20 未満の範囲の データに対するヒストグラムを描く場合は、 using を利用して以下のようなデータに変換して読ませます:
データとこの x 座標の関係は階段関数ですから、 floor() を使えば簡単に実現できます:
using (floor($1/5.0)*5.0+2.5):(1)y 座標は 1 なので、(1) とかっこが必要です。
そしてそのような入力に対して smooth frequency を使えば、 y 座標の 1 の合計、すなわちそのようなデータの個数が 同じ x 座標毎にまとめられるので、結局、
2.5 (0 以上 5 未満のデータの個数)のようなデータを描画するのと同じことになるわけです。 あとは、これを with boxes で書けばめでたくヒストグラムのできあがりです (s f は smooth frequency):
7.5 (5 以上 10 未満のデータの個数)
12.5 (10 以上 15 未満のデータの個数)
17.5 (15 以上 20 未満のデータの個数)
plot 'data' u (floor($1/5.0)*5.0+2.5):(1) s f w boxes fs s 0.5123 の記事にはより洗練されたスクリプトがのっていますので、 全体のスクリプトはそちらを参照してください。
なお、元記事の人は、さらに
using (floor($1/5.0)*5.0+2.5):(1):(0.5) with yerrorbarsとして y 誤差線をつけたいが、 これだと高さ 1 のところに点が描かれるだけ、と書いていますが、 これだと smooth frequency がないので 当然 y 座標は高さ 1 になるだけですし、 誤差線も 1 万行だと y 座標のスケールから考えて 0.5 という幅の誤差線は、 点になっても当然です。 しかし、これを例えば
using (floor($1/5.0)*5.0+2.5):(1):(100) s f with yerrorbarsとしてうまくいくかというとそうではありません。
table 出力を出させてみればわかりますが、 現在の smooth frequency は 2 次元データしか見ておらず、 3 番目以降のデータは y 座標と同じにしてしまうのです。 ただ、これも本来は、y 座標と同じ処理を 3 番目以降のデータにもほどこすのが筋のような気がします (実際、そのようなコードも入っているのですが、 smooth frequency ではその部分を使っておらず、 y 座標で上書きしてしまいます) ので、 時間のあるときに修正可能か考えてみたいと思います。
MS-Windows から Xming で Linux の gnuplot を起動して、 その X の画面を Alt+PrintScreen でキャプチャして MS-Windows 上で PowerPoint などへコピーペーストしているのだが、 その X のウィンドウに枠やタイトルバーがついているのをどうにかできないか、 毎回トリミングしないといけないので、 という質問がありました (128)。
それに対して、gnuplot で png 画像にしたら、 という意見がありましたが、 set term png して set output して MS-Windows に転送して、 と結構手間がかかる、という話でした。 それに対しても、作業ディレクトリを Samba にしたら、 という回答がきていました。
一連の作業の手順が同じであれば、 スクリプトを使うとか bind を使うとかで解消できるような気もします。
例えば、上 にあげた 95 番の記事のような bind を利用して、 「set term png ; set out 'hoge.png' ; replot ; set out」 をなんらかのキーに割り当てて、そのキーで png にし、 WinSCP のような Unix と MS-Windows 間の GUI の scp ソフトを使って コピーする (その後ファイル名を適当に変更する)、 などとすれば多少手間は減らせます。
または、Xming はよく知りませんが、 単純に Unix 上であれば、ウィンドウマネージャの機能を使って gnuplot のグラフのフレームを消すことはできなくはありません (ただし使っているウィンドウマネージャに依存します)。 例えば、私は普段 fvwm (2.4.X) を使っていますが、 fvwm の初期化ファイルで 「Style "noframe" NoTitle, NoHandles, BorderWidth 0」 のようにしておいて、 gnuplot 側では、「set term x11 title "noframe"」 としてグラフを描かせると、 gnuplot のグラフウィンドウの枠が完全に消えます。
Unix 上でウィンドウを画像にキャプチャする際は、 xwd とか ImageMagick の import などを使いますが、 import はデフォルトでは枠はつけません (逆に -frame で枠つきで画像化する)。 そういうものを Unix 上で利用する、という手もあるかもしれません。
wxt, qt は X11 に比べて何が良くなるのか、 という質問がありました (133)。 Solaris の古い環境で ライブラリなどのインストールが大変そうだから、 使う価値があればやってみようかと思う、という話のようです。
それに対して、自分で試したら、 マウスホイールを使って範囲指定ができるけど 最近の gnuplot なら wxt 以外でもできるのでは、 最近の Linux はデフォルトが wxt で x11 にするとかなり見劣りする、 MS-Windows でまずは試してみたら、 といったような回答がありました。
wxt terminal 上で特別にできること、 というのは実はそんなにあるわけではありません。 むしろ、pango や cairo などのライブラリにより グラフのレンダリング、文字のレンダリングが綺麗になるところが 大きな特徴でしょうか。 フォントも fontconfig 管理になるので x11 に比べれば指定するフォント名などのフォント管理は 多分だいぶ楽でしょうし、 UTF-8 文字列なども x11 terminal に比べれば 適切に処理されやすくなっているだろうと思います。
なお、そこから派生して、いつまで古い Solaris を使っているんだ、
といったような意見もでていたようですが、
実はうちでは Solaris 9 のマシン (Ultra10) が健在で、
gnuplot に関する作業のほとんどをその上でやっていたりします (^^)
その Solaris に wxt, qt も入れてありますが、
Solaris 9 だとデフォルトの gtk とかのライブラリが古いので、
確かに wxt のインストールはそれなりに苦労しました
(
「Unix に関するメモ等 (10/10 2006)」 参照)。
ただ、特に wxt でないと困る、ということはないので、
普段は私は x11 terminal を使用しています。
[0:2*pi] で sin(x), [-2*pi:0] で cos(x), [-2*pi:2*pi] で tan(x) を描画するにはどうしたら、 という質問がありました (140)。
FAQ の一つのような気がしますが、 3 項演算子を使って不要な部分を 1/0 で切り捨てる、 という標準的な回答がついていましたが、 「情報やメモ (12/21 2012)」 で紹介した通り、 最近の CVS 版ならばグラフに個別に範囲指定をすることでも 行うことができます。
set yrange [-2:2]
set grid
plot [-2*pi:2*pi] tan(x) lt 3, [0:2*pi] sin(x) lt 1, [-2*pi:0] cos(x) lt 2
pm3d map 上に x=1 のような直線を描きたいが、 nohead の arrow だとカラーマップの下に入って見えなくなるし、 媒介変数表示だと pm3d map では表示されない、 という質問がありました (144)。
それに対して、描画の順番を入れかえたら、という意見がありましたが、 set arrow なので splot より前に指定せざるをえない、 と返ってきていました。 そして、直線は外部ファイルでデータを作って、 それを描画させる、という強引な解決策を取ったそうです。
まず、媒介変数表示で 「set parametric ; set pm3d map ; splot 1,u,0」のようにしても 表示されないのは、多分 set pm3d map で塗る面がないからでしょう。
また set arrow だと上書きされる、というのには解決法があります。 gnuplot-4.0 以降では set arrow に front, back のオプションがあり、 front を指定するとグラフの最上位に表示されますから消されなくなります:
set pm3d map
set arrow 1 from 1,0,0 to 1,10,0 nohead front lt -1
splot sin(x+y)