ページが長いので「しおり」の仕組みを用意してみました。
「しおり用」と書かれた所をクリックしてからブックマークに入れると、
それはページの先頭ではなく、その箇所へのブックマークになります。
(03/03 2006)
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
gnuplot の print コマンドを利用して、 シェルスクリプト内で関数電卓代わりに使うという話がありました (844)。
その中で、print の出力が標準出力ではなく、 標準エラー出力になっていること、 および gnuplot プロンプトが標準出力に出されていることが 議論されていました。
確かにデフォルトではそのようになっていますが、 gnuplot の「出力」はグラフ出力、ヘルプ出力などもあって面倒なので、 そのような仕様になっているのでしょう。 ごく初期の gnuplot (gnuplot 2.0) からそうなっているようですが、 gnuplot-1.10A (TurboC 版) ではプロンプトの出力には cputs() などという関数が使われています。
現在の gnuplot (gnuplot-4.X) では、 set print で出力先を切り替えられますので、 標準出力に設定することもできるようになっていますが、 例えば
echo 'print sqrt(2)' | gnuplot -e 'set print "-"' -のようにしても、プロンプトも相変わらず標準出力に出るようです。 それだったら、デフォルトの仕様のまま使用して、 標準エラー出力をファイルに落として標準出力を捨てる方がましかもしれません。
gnuplot の (Emacs 風の) キーバインドをカスタマイズしたい、 という質問がありました (858)。
「Emacs 風の」ということは、コマンドラインの編集の際の キーバインドのことだと思いますが、 現在 (4.4.X) の gnuplot はコマンドライン編集機能として、 以下の 4 つの状態をサポートしています (コンパイル時に configure へのかっこ内のフラグで決定される)。
BSD Editline ライブラリのサポートは gnuplot-4.4.X からで、 それ以前はありませんでした。 gnuplot の configure スクリプトには、 Editline ライブラリでは UTF-8 はサポートしていない、 と書かれていますが、現状はよくわかりません。
組み込み版の編集機能については help editing に説明がありますが、 src/readline.c の中にキーコードが直接書かれているので、 基本的にはそのソースをいじらない限りカスタマイズはできません。
GNU readline の場合は、859 番の記事にも書かれていましたが、 $HOME/.inputrc でカスタマイズできるようです。 詳しくは、 GNU readline ライブラリのマニュアルを参照してください。
BSD Editline ライブラリ (libedit) は、 ところどころ sh, vi に関する言及もあるようですから、 もしかしたらデフォルトでは sh や vi 風のキーバインドを 提供しているものなのかもしれません (使用したことはありません)。 これは、現在のディレクトリかまたは $HOME の .editrc を読むようで、 それでカスタマイズできるようです。 付属のマニュアル (man editrc) を参照してください。
なお、現在の gnuplot には bind というコマンドもあり、 help bind を見るとこれでもキーバインドを設定できると書いてありますが、 これはコマンドライン編集のキーバインドではなく、 グラフウィンドウ上での動作のためのキーバインドです。
格子点を打ったり、軸を矢印にしたり、key をグラフの左に出したりしたい、 という質問がありました (861)。
軸を矢印にするのは 862 番の記事にもある通り set arrow でできます。
key をグラフの左の外に出すのは、gnuplot-4.0 までは実はできず、 「set key left outside」は実質的には機能していませんでした (inside になったり、または right outside になったりする)。 gnuplot-4.2 から key の配置の仕組みがだいぶ変更され、 それによってそれ以降のものでは「set key left outside」 が正しく機能しますので、4.2 以降のものを使用すればいいでしょう。
座標が整数の場所に格子点を打つ一つの方法は、 862 番の記事にもあるようにそのような整数点のデータを用意して それを with dots (または points) で出力する、という方法でしょうが、 gnuplot-4.4 以降ならば別な方法もあります。
# set samples 100 # デフォルトが 100 なのでこちらは多分不要'++' は、2 次元の疑似データを生成する疑似ファイルです (help datafile special-filenames 参照)。 データ点の個数は、set samples と set isosamples の第 1 引数で制御できます。
set isosamples 100 # デフォルトが 10 なのでこちらは必要の場合もある
set xrange [-2.5:5.5]
set yrange [-3.5:8.5]
plot '++' using (int($1)):(int($2)) with points
もう一つ、'+' と plot for を使う別解も紹介しましょう。
# set samples 100 # デフォルトが 100 なので多分不要'+' は、1 次元の疑似データを生成する疑似ファイルです。 これを for で繰り返し使用しています。
set xrange [-2.5:5.5]
set yrange [-3.5:8.5]
ymin = -3
ymax = 8
plot for [y=ymin:ymax] '+' using (int($1)):(y) with points lt 1 pt 1 not
set size ratio を使ってもラベルや目盛りの刻みのために縦横の比が 1:1 にならない、という質問がありました (870)。
set size ratio は、特に gnuplot-4.2 以降では、 グラフ部分のアスペクト比の指定であって、 その回りにあるラベル等の幅は考慮しません。 だから、それも含めた描画要素全体を正方形にしたいのならば、 むしろ使用している terminal の size オプションで縦、 横を同じ値で指定すべきです。
set term x11 size 480,480ただし、4.0 以前の gnuplot や terminal によって (size オプションをサポートしていないものなど) はそうならない可能性はあります。
set size square
set title "Hoge" font ",20"
plot sin(x)
y 軸に平行な直線を引きたい、という質問がありました (872)。
データファイルが必要か、ということでしたが、 それに対して set parametric を使って表示する方法が紹介されました。 しかし、一番手軽なのは set arrow nohead を使う方法だろうと思います。
前回の報告 (11/02 2010)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
上の各項目の最後のかっこ内に日付が入れてありますが、 それらは ChangeLog に書かれている日付です。 今までも自分のメモ代わりに日付を書いてあったのですが、 公開の際にはそれを消していました。 ただ、あった方が便利な場合もあるかも、と思い、残しておくことにしました。
最近はたて続けに canvas terminal への改良が行われていますが、 極座標に関する改良も大きいと思います。 極座標に関しては、具体的には以下のような改良が行われています。
また、emf terminal に関する改良の一部分は、 gnuplot Q&A 掲示板 ででた松岡さんの提案によるもののようです。
前回の報告 (09/21 2010)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
多少間が空いてしまいましたが、上のうち新しい機能、 仕様の変更としては以下のものがあります。
2 つ目のものはどのような影響があるのかは、まだよく確認していません。 また、最後から 2 つ目のものは、以下のようなもので、
set yrange [* : 100<*<200]これは、y の自動縮尺の上限を 100 から 200 の間に設定するようです。
(cf. 「情報やメモ (12/06 2010)」)
gnuplot-4.4.1 が出てまだ 2 週間ばかりですが、 いくつかのバグの修正ということで gnuplot-4.4.2 が出ました。 配布物に含まれる NEWS には、以下のように書かれています。
gnuplot 4.4.2 での新しい機能、変更、修正
なお、ドキュメント等には変更はありませんので、 4.4.1 用のものがそのまま利用できます。
(cf. 「情報やメモ (01/07 2011)」)
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
少し報告を先延ばしにしていましたが、windows terminal で、 enhanced 文字を使うと変に文字が小さくなることがある、 という報告がありました。
だいぶ長いスレッドになってしまいましたが、 wgnuplot 4.2 くらいからある問題のようで、 グラフウィンドウを別なウィンドウで隠したり、 リサイズしたりするとフォントが変わったりするような妙な問題でした。 フォントの初期化の問題だろうということで、 この掲示板の上で松岡さん、kakuto さんの協力を得て、 なんとか一通り解決することができました。 現在の CVS 版、および gnuplot-4.4.1 では直っています。
ついでに x11 terminal でもフォントの初期化に関する問題をみつけたのですが、 こちらも現在の CVS 版、および gnuplot-4.4.1 では修正されています。
(2209 の記事から始まるスレッド 「文字が小さい」)。
jpeg terminal で「gd-jpeg: JPEG library reports unrecoverable error: ...」 のようなものが出る、という問題が報告されました。
これは、jpeg library のバージョンが上がっていて (jpeg8b)、 それにともなって MS-Windows 上では boolean 型のサイズの定義が 強制的に入るようになっていて、 それが gd lib の boolean とぶつかるために起きる問題のようです。 MS-Windows 上で起こるようです。 gd ライブラリをそれに合わせて適切にビルドし直せば問題はないようです。 こういうのは、ビルドする立場にとってはやや頭の痛い問題ですね。
(2285 の記事から始まるスレッド 「jpeg ターミナル」)。
以前から気になっていたのですが、post terminal で日本語指定をすると、 日本語文字列内の半角スペースが「・」になる現象が起きていました。 山賀さんの gnuplot+ ではそれは起きないので、 gnuplot+ のようにコンポジットフォント (全角と半角のフォントを合成した PostScript フォント) を使うべきかなと思って質問してみました。
すると、どうやらこれはフォントの問題のようで、 IPA フォントなどを使えば問題ないようです。 うちは Solaris (9) 付属の HG-MinchoL, HG-GothicB の TrueType フォントを使っていましたが、どうやらそれが原因のようです。
松田@東京電機大 さんから enhanced 指定を使って、 文字列の中でフォントを切り替えて指定する回避策を教えてもらいました。 現在の gnuplot は文字列値を返す関数も作れたり、 文字列の連結も容易にできるので、 それらを使えばそれほど手間なくそういうこともできそうです。
なお、コンポジットフォントの仕組みも少し調べてみたのですが、 どうやら単純に prologue ファイルを作れば済むというものでもなく、 山賀さんがやっているように全角文字を出力するときに 8 進に直し、 さらに全角文字と半角文字の開始位置に特殊コードを埋め込む必要もあって、 だいぶ gnuplot 本体にも手を入れないといけなさそうなので、 そちらの方向はあきらめました。
(2314 の記事から始まるスレッド 「post term での日本語文字列内の半角スペース」)
gd terminal (png/jpeg/gif) でのフォント指定で、 FontConfig 対応の gdlib を使うと FontConfig でのフォント指定しかできず、 従来のフォントファイル (TrueType 等) を直接指定することができなくなる、 という問題に関するスレッドを立てました。
そもそも、gd ライブラリにパッチを当てないと FontConfig の切り替えはうまくいかないのですが、gnuplot の方で、 開発の途絶えている gd ライブラリでそれを仮定したパッチを作るのは いかがなものかと話を切り出したのですが、 松岡さんから以下のような情報を頂きました。
これにもとづいて、上の FontConfig の問題を解決するパッチを作成し、 最近それが CVS 版にめでたく採用されました (cf. 「情報やメモ (09/21 2010)」)。
(2318 の記事から始まるスレッド 「gd.trm でのフォント指定の問題」)
松岡さんから gnuplot-4.4.1 リリースに関する報告がありました。
前回の報告 (08/19 2010)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回は gnuplot-4.4.1 のリリース作業があったせいか、 CVS 版の更新作業はそれほど行われていないように感じます。
gd.trm に対する改良は、libgd 2.0.36 以降 Fontconfig への対応が行われたことへの対応ですが、 そのためにはパッチが当たった libgd を使う必要があります。 これを利用すると Fontconfig 風のフォント指定も可能になりますし、 従来の TrueType フォントの直接指定も可能になります。 なお、現在の gnuplot-4.4.0, 4.4.1 ではその辺りが中途半端になっていて、 残念ながら両者が可能、とはなっていません。それが改良されています。
log の底の制限とは、従来は 1.1 以上だったようで、 現在はそれが 1.0 より大きいもの、となっています。
value() は新規に導入された関数で、文字列値を与えて、 その文字列を名前とする変数の値を返し、 数式を指定した場合は、その値を返すようになっています。 gnuplot には配列変数がないのですが、 これを利用すればある意味で配列変数も使えることになります (なお、まだ実際には確認していません)。
eval sprintf("a_%d = %d",0,0)eval に for が使えないのでやや苦しいですが、 これは if と reread を使えば解消できるでしょう。 上のような疑似配列変数 a_0, a_1, ... は今までも作れたのですが、 従来はそれを使う際に直接 a_0 と指定するしか手段がなかったので、 事実上配列変数とは言えないものでした。 また、マニュアルにも書かれていますが、 現在は strcol() で各列の文字列としての内容を取得もできますので、 value() を利用すれば変数名をデータファイルから入力することもできます。 そちらの方が配列としての利用価値は高いでしょう。
eval sprintf("a_%d = %d",1,1)
eval sprintf("a_%d = %d",2,2)
eval sprintf("a_%d = %d",3,3)
f(x,i) = (i==0)? value("a_0") : f(x,i-1) + value(sprintf("a_%d",i))*x**i
# f(x,i) = a_0 + a_1*x + a_2*x**2 + ... + a_i*x**i
plot for [i=1:3] f(x,i) w l lt i
(cf. 「情報やメモ (09/21 2010; no.2)」 「情報やメモ (11/02 2010)」, 「情報やメモ (04/08 2011)」)
gnuplot-4.4.1 がリリースされました (09/12 2010)。 その配布物に含まれる NEWS には、以下のように書かれています。
gnuplot 4.4.1 での新しい機能、変更、修正
日本語マニュアル、wgnuplot の日本語化キットも更新済みです。
前回の報告 (07/16 2010)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
enhanced 文字列回りの修正は、 gnuplot Q&A 掲示板 でも話題になった話で、 また後でまとめておきます。
set key opaque は、通常は key の各項目は各グラフと同時に描画されるので、 後のグラフが key の部分を上書きしうるのですが、 set key opaque とすると、グラフの描画が全部終った後で key の描画を行うようになりますので、 むしろ key がグラフの上に描かれるようになります。 以下にサンプルを上げておきます。
(cf. 「情報やメモ (09/21 2009)」)
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
各行に、「緯度、経度、その地点での値」のデータがあるとき、 これを使って 3 次元球面の等高線を書けないでしょうか、 という質問がありました (824)。
実は、その前の記事も等高線の話だったのですが、 そちらは回答もついていましたし、 難しそうではない話題だったのでこちらの球面上の等高線を考えてみます。
なお、こちらの質問にもちゃんとした回答がついていて、 「一旦球面上ではなく、平面上の 2 変数関数であるとみて、 その等高線を作らせ、その等高線データを table 出力で吐きださせて、 それを再び球面上のデータとして描画させたらどうか」というものでした。 実際にそれをやってみましたが、多少調整が必要なようです。
まず、使用したのは以下のようなデータ (data0) です。
[phi] -180 [z(phi,-180)]
[phi] -179 [z(phi,-179)]
...
[phi] 179 [z(phi,179)]
(空行)
これに対する等高線データを以下のようにして取ります (これは回答にも書いてありましたが help contour にその例があります):
unset surfaceusing 2:1:3 としているのは経度を x を 1 列目に変更するためですが、 それは set mapping spherical を使用するためにそうしています。 ただ、それはこの時点ではなく、 もちろん最終的な描画の時点で using で順番を入れ変えても結構です。
set contour
set cntrparam levels incremental -1,0.2,1
set table 'data1'
splot 'data0' using 2:1:3 w l
unset table
これによる等高線データ data1 を球面上の曲線として描くには、 set mapping spherical, set parametric と index 指定を使います:
# index 番号を凡例文字列に変換
i2key(j)=sprintf("%.1f",1.0-j*0.2)
set view 80,95
set angle degrees
set mapping spherical
set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]
# 以下 4 行は緯度、経度の描画用 set urange [0:360]
set vrange [-90:90]
set parametric
set isosamples 9,9
splot cos(u)*cos(v),sin(u)*cos(v),sin(v) w l lt -1 notitle,\
for [j=1:9:2] 'data1' using 1:2 index j w l title s(j)
splot の最初の部分は、緯度、経度を数本書いて、球の枠を作っています。 その次の for [j=1:9:2] で等高線を 1 つ置きに 0.8 から -0.8 まで書いています。 set mapping spherical により、1 列目が経度、2 列目が緯度として使われて、 半径 1 の球面上にデータが描画されます (help mapping 参照)。 やや見にくいですが、等高線は微妙に交わらずに、 極大は 2 点、極小も 2 点となっていることがわかります。
これで一応天気図の等圧線のようなものが描けることがわかりますが、 この等高線の間隔の選び方や、 見る角度 (set view) の選び方が実はそれなりに大事で、 それを上手く選ばないと球面上の曲線には見えません。 そういう場合は、set hidden3d で裏側を消してしまう方がいいかもしれません:
ただし set hidden3d を使うと、 陰線処理のために面が長方形に変えられてしまうので、 見比べてもわかりますが、枠の緯線、経線が折れ線になってしまいます。
また、等高線ではありませんが、 元データから直接 pm3d で曲面上に各地点でのデータの値を 色で表現することもできます:
set view 80,95
set pm3d
set angle degrees
set mapping spherical
set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]
unset surface
splot 'data0' using 2:1:(1):3 every 10:4 notitle
球面上の関数値を見るには、これが一番手軽といえば手軽です。
Mac OS X で AquaTerm をインストールして、 gnuplot-4.4.0 をインストールして「plot x」としてみたが何も出ず、 AquaTerm.app を強制終了するとエラーが出る、 という話がありました (841)。
Mac の掲示板の方で質問したら、という回答があり、 それに従ってそちらで質問されたようですが、そちらでも回答はないようです。
エラーが出る、とあってそのエラーメッセージも書いてあったのですが、 それは AquaTerm 強制終了時のエラーで AquaTerm が出しているものなので、 あまり関係はなさそうに思います。 むしろ気になるのは plot してみると無反応になる、という状態です。 もしかして、plot の前に「set term aqua」するのを忘れている、 という可能性もあると思いますが、 手元には Mac はないので確認はできません。
ただ、4.4.0 はまだ新しくて不安定なところもあるので、 問題を切り分けるためにも、とりあえず 4.2.6 あたりで試してみて、 それがちゃんと動くように環境を整えてから 4.4.0 にチャレンジする方がいいように思います。
前回の報告 (06/13 2010)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
terminal ドライバのところの win.trm の初期化の問題は、 gnuplot Q&A 掲示板 に出た質問 (2209 番からのスレッド) に関する、主に角藤さんによる対処が取り入れられたものです。 まだ少し妙な問題が残っているようなので、 その辺が一段落ついたらまとめようかと思っています。
今回の大きな変更は、「with ellipses」と、 ほぼすべての描画スタイルでの variable color のサポートでしょう。 その他の修正もこれに関するものが多いようです。variable color は、 マニュアルではアナウンスされていたものの利用できないものが多かったのですが、 やっとその辺りが整理されたようです。
実際の例は、上の ellipses_style.dem, varcolor.dem を見てもらうのが一番ですが、 まだ最近すぎて本家 (http://www.gnuplot.info) のデモギャラリーにも載っていないようなので、 そのうちのいくつかの X11 の出力 (を gif にしたもの) を紹介します。
色んな楕円、色んなスタイルで色んな色が使えることがわかると思います。 demo のソースとデータを見れば使い方もわかると思いますが、 それらはとても簡単に行えます。
(cf. 「情報やメモ (08/19 2010)」)
gnuplot Q&A 掲示板 に以下のような質問がありました。
MS-Windows XP 上の wxt terminal でフォントを指定したが うまくいかず化けてしまう (2203 の記事 「フォント指定」)これは、質問者の状況の把握がしにくかったこともあり、 かなり長いスレッドになってしまいましたが、備忘録も兼ねて、 ここにそれなりにまとめておきます (カッコ内の番号は記事番号)。
公式サイトで公開されている MS-Windows 用の gnuplot-4.4.0 バイナリでは、
png (gif,jpeg) terminal と wxt terminal は、
ともにフォントについては fontconfig ライブラリを使用していて、
特に png/gif/jpeg terminal については、
従来のような TrueType フォントをパスつきで直接
'./cmmi10.ttf' のように指定したり、GDFONTPATH での指定もできず、
fontconfig に従ったフォント指定をする必要があります。
(2204,2206,2212,2214,2216,2217)。
これについては、kakuto さんから 2.0.35 以前の gdlib のバグであり、
パッチ (2218) を当てるか、
2.0.36-RC1 の gdlib を使えば fontconfig をリンクしてあっても、
従来の形式も利用できる、という説明がありました。
現在松岡さんが公開している CVS 版ではそのようなものにしてあるそうです。
(2218,2250,2254,2259,2260)
MS-Windows 版の fontconfig ライブラリでは、 デフォルトではフォントは「C:\Windows\Fonts」を検索しますから、 そこに TrueType フォントを入れておけばちゃんと検索してくれるようです (2213)。
それ以外の置き場所を設定したい場合は、 設定ファイルを書くのですが、 それは MS-Windows 版の gnuplot-4.4.0 を展開したところにある binary ディレクトリの下の etc\fonts ディレクトリの、
<dir>WINDOWSFONTDIR</dir>の下に、TrueType フォントを置くディレクトリを <dir> と </dir> で囲んで書いた行を追加する (2216)
のいずれかを行えば、 ちゃんとそちらのディレクトリを検索してくれるようになります (ただし、本当は前者の fonts.conf を直接修正するのはあまりよくない)。
ただし、この設定については fontconfig ライブラリは環境変数 FONTCONFIG_PATH を参照するので、 それが別なところに設定してあったりすると、 上の設定を見てくれません (2263)。
また、MS-Windows ではよくありがちな、
スペースが含まれるディレクトリ名もうまく設定できないようで、
単純に "" で囲んだり、\ をつけた位ではうまくいきませんでした
(2225)。
(2216,2225,2228,2233,2236,2253,2263)
fontconfig でフォントを指定する場合は、 TrueType フォントファイル名とは別の、 フォントファイルで定義されているフォント名を指定しなければいけません。 それを調べるツールとして、 fontconfig ライブラリには通常 fc-list というものが付属しています。 これを使うと、現在 fontconfig ライブラリが認識して使える フォント名の一覧が表示されます。
しかし、gnuplot-4.4.0 にはそれが付属していないので、 実は fontconfig が認識しているフォント名が正確にはわかりません。 基本的には、MS-Windows が認識するフォント名と同じでいいようですが、 松岡さんが公開している、新しい CVS 版のバイナリからは fc-list を fc-list-gp.exe という名前で付属してくれることになりました。 これで一応 fontconfig が設定パスを認識しているかを含めて確認ができます。
ただ、fc-list の出力は UTF-8 文字列として表示されるようなので、
コマンドプロンプトそのままでは文字化けしますので、
リダイレクトして UTF-8 が表示できるエディタ (メモ帳も可) などで見るか、
nkf のようなコード変換をしてくれるフィルタにかける必要があります。
(2221,2224,2226,2227,2238)
実は、質問者が利用していたのは、cmmi10.pfa という、 LaTeX の computer modern フォント由来の PFA 形式のフォント (PostScript の ASCII 形式のフォント) だったようでした。 fontconfig は PFA も PFB (PostScript の バイナリ形式のフォント) も一応認識はできるようですが、
といった状況のようです。 よって、少なくとも MS-Windows 用の gnuplot-4.4.0 の png/jpeg/gif, wxt terminal では、PFA, PFB フォントは使えない場合もある (フォント名の問題) し、 使えたとしても文字化けする可能性もある、 ということであまりおすすめはできない、ということになります。
少なくとも cmmi10 に関しては TrueType フォントもあって、
それならば上のような問題は (ほぼ) 発生しないので、
png/jpeg/gif, wxt terminal ではそれを使うべきだと思います。
(2229,2231,2232,2234,2239,2241,2243,2255)
上記のテスト等は、単にフォントを適当な場所に置いて (コピーして) 実験を行ったのですが、 MS-Windows にはどうやら (お行儀のよい)「フォントのインストール」 という作業があるらしくて、それに関する話題もいくつかありました。
ただ、問題のフォント (cmmi10) は、 PFB や PFM ファイルはそれではうまくインストールはできないらしいです (壊れているとか表示される)。
フォントが MS-Windows に正しく認識されれば、
それは MS-Windows の付属のツールでフォントの文字コード表を確認できる、
という情報もありました (2251)。
(2240,2242,2244,2245,2246,2247,2248,2249,2251,2255,2256,
2257,2258)
最後に、フォントのエンコーディングの話、 各 terminal とエンコーディングの話などをまとめておきます。
元記事の方は、そもそも enhanced mode を使って「'{/CMMI10 \272}'」 (\272 は 8 進表記) のように指定していたのですが、
set encoding utf8のようにする必要がある
set ylabel '{/CMMI10 \272}'
set term png enhとすると、タイトルは「λ□」になってしまうが、 wxt terminal ではなぜか正しく「λκ」と出る (2261)。
set out "file.png"
set title '{/Cmmi10 \270\267}'
plot x
set out
set term png noenhのようにすれば「λκ」を無理矢理出せなくはない (2261)
set out "file.png"
set title "¸∙" font "Cmmi10"
plot x
set out
といった情報がありました。
(2203,2213,2219,2230,2231,2232,2235,2239,2243,2261)
結局、wxt や png terminal では PFA ではなく TrueType を使うのが無難なんだけど、 場合によってはそれもうまくいかなかったり、 wxt と png で挙動が違ったりすることがある、 という厄介な状況であることがよくわかった、という感じでしょうか (^^;
(cf. 「情報やメモ (06/20 2010)」)
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。 これも半年以上だいぶためてしまいました (^^;) が、 既に報告済みのものや、それほど報告の必要のないものもありましたので、 まあタイミングとしてはそれほど悪くもないかと思います。
4.4.0-rc1 が出たときに、 今後 wxt がデフォルト出力形式になっていくのだろうか、 といったような議論を松岡さんと少ししました。
その後 4.4.0 では実際にその方向で動いて、 おかげで MS-Windows 用バイナリも従来に比べてだいぶ大きくなりました。
(2160 の記事から始まるスレッド 「4.4.0-rc1」)
gnuplot-4.4.0 がリリースされたのを、 ここ (「情報やメモ (03/14 2010)」) gnuplot 掲示板でも報告したのですが、 今回の gnuplot-4.4.0 の MS-Windows 版、Cygwin 版、DJGPP 版のバイナリは、 松岡さんがコンパイルしたものが本家から配布されています。 どうもありがとうございます。そして、どうもご苦労さまです。
MS-Windows 版は wxt terminal がデフォルトになりましたが、 GNUPLOT.ini か環境変数 GNUTERM で設定することで今まで通り win terminal をデフォルトにできます (README.Windows 参照)。
(2198 の記事から始まるスレッド 「gnuplot-4.4.0 リリース」)
MS-Windows XP 上の wxt terminal でのフォントの指定の仕方に関する 質問がありました。これはかなり長いスレッドなので、 後日別にまとめることにします (cf. 「情報やメモ (06/22 2010)」)。
(2203 の記事から始まるスレッド 「フォント指定」)
松岡さんから、MS-Windows 用のフリーのプログラマー向けエディタ SciTE 用の gnuplot の編集モードのファイルを作成したと報告がありました。 そこから派生して、プログラム実習用のいいエディタはないか、 NotePad++ や SciTE は AWK をサポートしてないようだけど、 と質問したのですが、
という情報がありました。
さらに、今の gnuplot-4.4.0 の MS-Windows 用バイナリは、 wxt をサポートしているためにだいぶ配布ファイルが大きくなって、 重くなってしまっている、という話をしたら、 CVS 版用に wxt, cairo 関係を抜いて win terminal や gd ベースのもの (従来の 4.2.X 系統と同等) の軽いバイナリを作成して公開してもらえることになりました。 現在、松岡さんの以下のサイトで gp45-winbin-small.zip という名前で順次新しいものが公開されています。
(2264 の記事から始まるスレッド 「Customization of SciTE for gnuplot 4.4.0 for window」)
前回の報告 (05/07 2010; no.2)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回は、大きな変更はなさそうに思いますが、 しいて上げれば hidden3d モードでの lc variable のサポートでしょうか。 どのようなものなのか実際には確認はしていませんが、 それなりにおもしろいかもしれません。
なお、今回は更新がある度に少しずつ記録を取っていったので、 ほぼ予定通り前回から 1 ヶ月後の報告となりました。 これなら楽なので、今後もこの方式で行きたいと思います。
(cf. 「情報やメモ (07/16 2010)」)
gnuplot-4.4.0、および CVS 版 gnuplot で、 parametric モードでのグラフの key のタイトルが おかしくなっている問題を見つけました。 通常 (gnuplot-4.2.6 以前)、
set parametric
plot sin(t),cos(t)
splot f(u,v),g(u,v),h(u,v)
とすると、key にはそれぞれ
sin(t), cos(t)
f(u,v), g(u,v), h(u,v)
と表示されていましたが、gnuplot-4.4.0 では
sin(t), sin(t),cos(t)
f(u,v), f(u,v),g(u,v), f(u,v),g(u,v),h(u,v)
と表示されるようになってしまっています。
開発者に報告したところ、05/10 2010 に修正がなされたようで、 現在の CVS 版 (および多分次期版の 4.4.1) では
sin(t),cos(t)
f(u,v),g(u,v),h(u,v)
と表示されるようになっています。
ただし、細かく言えば、
4.2.6 とはスペースが抜けている分違っているようです。
gnuplot-4.4.0 では、あるいはこの title が気にいらない場合は、 plot (splot) 命令の title オプションで明示的に key の title を指定してください。
前回の報告 (02/26 2010)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
新規の追加機能としては、set key の maxcolumns, maxrows オプション、 smooth の cnormal オプション、Voigt/Faddeeva 関数 voigt(x,y)、 set termoption の fontscale オプションあたりです。 また、Unix 系の人には、X11 app-defaults のインストール先が変わったことも注意が必要でしょう。
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
wxt terminal だと透明化ができるのに、 png terminal だと透明化ができない、という質問がありました (770)。
これに対し、truecolor オプションをつけたらうまくいく、 けど truecolor なしでできる別のマシンもある、 という話もありました。
さらに、wxt だとアンチエイリアスがかかるのに、 png terminal のグラフは汚い、という意見もありましたが、 それに対しては、pngcairo terminal でやるか、 svg 出力を png に変換するか、wxt の画面を gimp 等に貼り付けるか、 という回答が来て、pngcairo ならうまくいった、という返事がきました。
transparent fill (透明化の塗り潰し) 機能は、 開発版では 11/12 2006 に、 リリース版では gnuplot-4.4.0 からサポートされていて、 demo/transparent.dem で見れるようになっています。 その場合、png terminal では truecolor オプションをつけることが 必須になっていますから、 truecolor なしでできたのは pattern fill の透化の方か、 または 2006 年の機能追加直後の開発版のバグに起因しているのかもしれません。
現在、すべての出力形式が transparent fill をサポートしているわけではなく、 gnuplot-4.4.0 (開発版もほぼ同じ) では、 以下のものがそれをサポートしていると思われます (いくつかは未確認でソースから判断):
aqua, canvas, png, gif, jpeg, lua, pdf, svg, wxt, pngcairo, pdfcairoなお、gif, jpeg は、undocument ですが、 「set term gif truecolor」のように truecolor オプションを指定すると transparent fill が行えます。
各行に中心の x,y 座標と半径 3 列のデータがあるとき、 その各行に対応する円を描くことはできるか、という質問がありました (783)。
それに対して、postscript を覚えたら、 4.5 以降に plot with circles があるが面倒、 perl や ruby などでそのデータからパラメトリックの plot 命令のスクリプトを吐くプログラムを書いたら、 などの回答がありました。
上にもあるように、現在、gnuplot-4.4.0 以降で、 with circles というデータ描画が可能で、 3 列のデータを中心の x, y 座標、半径とみなすので、 まさにそのままのデータで描画ができます。 円の塗り潰し属性などは set style fill で設定します。
別解としては、「with points pt 6 ps variable」で 3 列目のデータを pointsize として利用して pt 6 で丸を描く、 という手もあります。これなら gnuplot-4.2 系でも可能です。 詳しくは、以下を参照してください。
system() で if や for などで何十行も書きたい場合はどうすれば、 という質問がありました (809)。
それに対して、\ を使うという回答がありましたが、 以下のようにするとうまくいかない、という返事がありました。
system("for i in 1 2 3 \ do \ echo $i \ done ")これだと、"" の間が 1 行だとみなされるのでだめでしょう。 ; を適宜入れて以下のようにするか
system("for i in 1 2 3 ; \ do \ echo $i ; \ done")または適宜改行を入れなければいけません。
system("for i in 1 2 3 \n\ do \ echo $i \n\ done")gnuplot-4.2 以降では、文字列の連結演算子 . もサポートされていますので、 以下のような書き方も可能です。
system("for i in 1 2 3 \n"\ . "do "\ . "echo $i \n"\ . "done")さらに文字列変数も使えますから、以下のようにもできます。
s = "for i in 1 2 3 \n" s = s . "do " s = s . "echo $i \n" s = s . "done" system(s)はたして、どれが書きやすいでしょうか。
gnuplot-4.4.0 の正式版がついにリリースされました (03/13 2010)。 その配布物に含まれる NEWS には、以下のように書かれています。
gnuplot 4.2 以降の新しい機能、変更、修正
ほぼ、 「情報やメモ (12/02 2009)」 で紹介した 4.4.0-RC1 のものと同じですが、 「修正」と「変更」に 2,3 追加があるようです。
日本語マニュアル等もなるべく早く用意する予定です。
(cf. 「情報やメモ (06/20 2010)」)
gnuplot Q&A 掲示板 に以下のような質問がありました。
複素数データの絶対値を明度、位相を色彩に対応させて表現したい (2182 の記事 「複素数データの表示」)gnuplot は 4.2 以降、色がかなり自由に指定できるようになり、 RGB 以外にもここで指摘されている HSV カラーモデル (H=色彩、V=明度) も使えるようになっています。
しかし、HSV カラーモデルが使用できるのはカラーパレットの設定だけで、 gnuplot のカラーパレットはスカラー値をカラーパレットへ変換することしか できませんから、 この質問のような 2 種類のパラメータから色への変換を行う場合には、 残念ながら使えません。 よって、この質問のようなことを実行するためには、 次の 2 つのことをクリアする必要があります。
松田@東京電機大 さんからは、Octave を使った回答が提示されましたが、 あえて gnuplot だけでやろうとすると、以下のような方法が考えられます。
いずれにせよ HSV から RGB へ変換するような関数が必要になりますが、 これは gnuplot 自身内部に持っているのですが、 ユーザが使えるようにはなっていませんので、 gnuplot スクリプトでそれを定義しなければいけません。 例えば以下の通りです。
f1(x)=floor(x*6)hsv2r(h,s,v),hsv2g(h,s,v),hsv2b(h,s,v) は、 0.0 以上 1.0 以下の h,s,v の値からそれぞれ 0.0 以上 1.0 以下の r,g,b の値を返す関数で、 hsv2rgb24(h,s,v) は 0.0 以上 1.0 以下の h,s,v の値から RRGGBB の 24 bit 整数を返す関数です。
f2(x)=x-floor(x)
hsvcomp(h,s,v,a,b,c,d,e) = ((f1(h)==a || f1(h)==b)? v: \
(f1(h)==c || f1(h)==d)? v*(1.0-s): \
(f1(h)==e)? v*(1.0-f2(h*6)*s): \
v*(1.0-(1.0-f2(h*6)*s)))
hsv2r(h,s,v)=hsvcomp(h,s,v,0,5,2,3,1)
hsv2g(h,s,v)=hsvcomp(h,s,v,1,2,4,5,3)
hsv2b(h,s,v)=hsvcomp(h,s,v,3,4,0,1,5)
f2int24(x,y,z)=65536*int(255*x)+256*int(255*y)+int(255*z)
hsv2rgb24(h,s,v)=f2int24(hsv2r(h,s,v),hsv2g(h,s,v),hsv2b(h,s,v))
これらを利用すれば、例えば上の 2 つの方法は以下のように行えます。 なお、データファイル data は、$1=x, $2=y とし、 複素関数 f(z)=f(x+iy) の値は $3 = f(z) の実数部分、$4 = f(z) の虚数部分、 であるとします。 まずは with rgbimage を利用する方法:
s=1.0次は with point pt 5 を利用する方法:
rmax=10.0 # |f(z)| の最大値
i={0,1} # 虚数単位
plot "data" using 1:2\
:(int(255*hsv2r(arg($3+i*$4)/(2.0*pi),s,abs($3+i*$4)/rmax)))\
:(int(255*hsv2g(arg($3+i*$4)/(2.0*pi),s,abs($3+i*$4)/rmax)))\
:(int(255*hsv2b(arg($3+i*$4)/(2.0*pi),s,abs($3+i*$4)/rmax)))\
with rgbimage
set pointsize 3ただ、いずれも色数の問題で、 普通の terminal ではまともに表示されませんから、 「set term png truecolor」などを利用する必要があるでしょう。
s=1.0
rmax=10.0 # |f(z)| の最大値
i={0,1} # 虚数単位
plot "data" using 1:2\
:(hsv2rgb24(arg($3+i*$4)/(2.0*pi),1.0,abs($3+i*$4)/rmax))\
w p pt 5 lc rgb variable
もう一つ、長さを V として出力した色グラフと 偏角を H として出力した色グラフの 2 つのグラフを作り、 それを別なソフトを利用して合成する、という手もあります。 これなら、個々のグラフを作るのは簡単だし、 上のような HSV から RGB への変換関数も不要、 という利点があります。
rmax=10.0 # |f(z)| の最大値この最後の hsvtoppm が PPM 画像から H,S,V 値を取得して合成した PPM 画像を作成するプログラムです。 PPM 画像形式はそれほど難しくはないので、自作も容易です。 例えば以下の通りです (フリーソフトでは見つからなかったので簡単に作ってみました)。
i={0,1} # 虚数単位
set term png
set out 'file-arg.png'
set pm3d map
unset colorbox
set palette model HSV functions gray,1,1 # H 画像の作成
set zrange [0:2.0*pi]
splot 'data' using 1:2:(arg($3+i*$4))
set out
set out 'file-abs.png'
set palette model HSV functions 1,1,gray # V 画像の作成
set zrange [0:rmax]
splot 'data' using 1:2:(abs($3+i*$4))
set out
! pngtopnm file-arg.png > file-arg.ppm
! pngtopnm file-abs.png > file-abs.ppm
! ./hsvtoppm file-arg.ppm -v1.0 file-abs.ppm | ppmquant 256 | ppmtogif > file.gif
3 つのファイルを指定して、それぞれのピクセルの H,S,V の値を取得して そこから作った RGB 値を持つピクセルを出力します。 バイナリ形式の PPM (P6) にしか対応していません。 また、ファイルの代わりに -v[value] と指定するとその値を定数値として 使用します (0.0 以上 1.0 以下)。
なお、gnuplot は palette mode で HSV 等を指定できますが、 それは内部に HSV 等から RGB への変換関数を持っているからです。 それをユーザに開放して使えるようにしてくれれば、 上の hsv2r(), hsv2rgb24() 等は用意しなくてもいいことになります。 そのようなパッチも作ってみました (CVS 版 gnuplot 用)。
これを当てると、gnuplot で col2rgb24(x,y,z,"name") という関数が利用できます。x,y,z は色の 3 成分、"name" は、 set palette model のモデル名を小文字にしたもので、 "rgb", "hsv", "cmy", "yiq", "xyz" が指定できます。x,y,z は 0.0 以上 1.0 以下の値で、 そのモデルに対応した変換を行い、RRGGBB の 24 bit 整数値を返します。 つまり上の、hsv2rgb24(h,s,v) は col2rgb24(h,s,v,"hsv") となりますし、(int(255*hsv2r(h,s,v))) 等も int(col2rgb24(h,s,v,"hsv")/65536) と書けることになります。
(cf. 「情報やメモ (11/08 2012)」)
うちで和訳を行っている gnuplot のドキュメントですが、 多くのフリーソフトの例にもれず、 ドキュメントの更新はソースコードの更新に比べて遅れがちで、 そのために実装とドキュメントのずれが起きている箇所がいくつかあります。
先日発売された山本昌志さんの「gnuplot の精義」(カットシステム) は gnuplot-4.2 系に関する情報を網羅した本ですが、 そこでもそのようなずれに関する指摘などがあります。 今回少し全体を読んでみて気がついた、 そのようなずれ、および日本語訳のミスなどに関して紹介しておきます。
set multiplot の rowsfirst, columnfirst を、 今までは日本語マニュアルでは
「列 (rowsfirst)、あるいは行 (columnsfirst) が先に埋められて行きます」と書いていましたが、正しくは逆で、
「行 (rowsfirst)、あるいは列 (columnsfirst) が先に埋められて行きます」と書くべきでした。先日修正しました。
png/gif/jpeg terminal のマニュアルの例には、
set terminal png medium size 640,480 \ xffffff x000000 x404040 \ xff0000 xffa500 x66cdaa xcdb5cd \ xadd8e6 x0000ff xdda0dd x9500d3 # デフォルトと書いてあるので、この設定による線色が あたかもデフォルトのように感じるかもしれませんが、 実はかなり前からデフォルトはこれとは違っています。 だからこれは単なる設定の例として見るべきなのですが、 今回開発者にこの点を指摘したところ、 この部分は削除して大幅に修正することになりました。
後方互換性を考えて上記のような色指定は一応残すものの、 正式にはオプションの色指定は最初の背景色のみを推奨する、 という形式になりました。現在のマニュアルは以下のようになっています:
書式: set terminal png {{no}transparent} {{no}interlace} {{no}truecolor} {rounded|butt} {linewidth <lw>} {dashlength <dl>} {tiny | small | medium | large | giant} {font "<face> {,<pointsize>}"} {{no}enhanced} {size <x>,<y>} {{no}crop} {<background_color>}
「gnuplot の精義」には、「fill solid 0.1」のような fill 指定が win terminal ではうまくいかない、と書かれています (p59)。 確かに 4.2 系の win terminal ではバグがあって fill solid がうまくいきません。 最近修正されたので、次期バージョンの 4.4 では使えるようになると思いますが、 実は win terminal の fill solid は色の強度ではなく、 ハーフトーンを使って実装していますので、 実質的に 0.00, 0.25, 0.50, 0.75, 1.00 の 5 段階の密度にしかなりません。 それ以外の中間密度は切り捨てで下の密度が使われますので、 例えば fill solid 0.1 は fill solid 0 (塗り潰しなし) と同じになってしまいます。
「gnuplot の精義」には、splot では set size ratio 2 のような指定は、 マニュアルには無効と書かれているけど実際には効果がある、 と書いてありますが (p94)、これは gnuplot-4.2.4 以前のバグで、 gnuplot-4.2.5 以降は本当に効かないようになりました。
「gnuplot の精義」には、「理由は不明ですが、Windows だと、 Inf を指定するとエラー (未実装) が発生します」と書かれています (p143)。 実は、set datafile binary に関しては問題が多い、 あるいはドキュメントとは異なる実装があることがわかって、 gnuplot-4.2.5 からは一旦一部の機能が停止されました。 Inf に関しても 4.2.5 以降からは使えないようになっています。
「gnuplot の精義」には、マトリックスバイナリの x 座標と y 座標の指定がおかしい、と書かれています (p146-147)。 これも datafile binary が大幅に改良されたときに入ってしまったバグのようで、 長く気がつかれなかったもののようです。 まだ修正される見込みはないようですが、 とりあえずマニュアルとは x 座標と y 座標が丁度逆に扱われているようなので、 using 2:1:3 のように指定することで回避はできます。
マニュアルには書かれていませんし、警告も出ませんが、 pipe を使ったデータ入力である "< command" の形式のデータファイル指定は、バイナリデータでは利用できません。 これも本来は警告を出すべきだろうと思いますので、 できればそのようなパッチを作ってみたいと思います。
「gnuplot の精義」には、set format の flags に # に関する記述があり、 使用するとエラーが起きる、等と書かれています (p202)。 # が gnuplot の gprintf() に実装されたのは gnuplot-4.2.5 からで、 しかも整数には使えず、e や f 等の不動小数にしか使えないようになっています。
「gnuplot の精義」には、png terminal の 「truecolor は、24 ビットカラーのことと思われますが、 マニュアルに記述がないので」と書かれています (p273)。 これはその通りで、マニュアルには書いてありませんが、 24 ビットカラーです。 現在の CVS 版のマニュアルには truecolor オプションに関する説明が 追加されています。
「gnuplot の精義」には、変数名の 2 文字目以降にはマニュアルには $ も使えると書いてあるが実際には使えない、と書いてあります (p288)。 これもその通りで、既に CVS 版のマニュアルではそれは削除されています。 どうやら $ が入っていたのは VMS への配慮のようです (一応 VMS も今だにサポート対象となっている)。
set datafile missing に関するヘルプドキュメントには、 「set datafile missing "?"」のように設定した上で、
1 10というデータを処理する場合、以下のようになると書いてあります。
2 20
3 ?
4 40
5 50
3 行目はデータが 1 つしかない、と見なされ、 x 座標は行番号 2 が使用され、3 は y 座標として使われるので、 (x,y)=(2,3) と見なされる
3 行目は完全に無視され、(2,20) の点と (4,40) の点の線が結ばれる
3 行目は無視されるが、(2,20) の点と (4,40) の点は線は結ばれない
しかし、[gnuplot の精義」には、1. のようには書いてなく、 1. の場合は 2. と同じであると書かれています。
実際には「gnuplot の精義」の方が正しく、 ヘルプドキュメントの方に誤りがあります。 実は上の 1. は「set datafile missing "?"」 を設定「しなかった」場合の挙動で、 その場合は "?" が正しく無視されないために そうなってしまうわけです。 これも開発者によればドキュメントの方を改訂するとのことです。
他にもいくつか気になるところなどがありましたが、 それは著者の方に連絡ずみです。
しかし今回改めて「gnuplot の精義」を読んでみましたが、 特に後半は gnuplot をプログラミング言語としても利用するような なかなかすごい例が載っています。 ルンゲ・クッタ法を用いて常微分方程式を数値計算してそのグラフを描くとか、 シンプソンの公式を用いて数値積分によってクロソイド曲線を描くとか、 フラクタル画像、ジュリア集合を描く、などといったサンプルが、 gnuplot だけでそれなりに簡単に行えることが示されています。 そのような利用法はほとんど想像していませんでしたが、 これなら gnuplot だけで大学の計算機実習を行うことも可能かもしれませんね (数年後に計算機実習をやらないといけなくなった (;_;))。
前回の報告 (08/13 2009)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
相変わらずだいぶさぼったせいで、かなりの追加、変更、修正があります。 このうち、主なもの (特に新しい機能や改良) をあげるとすると、 以下のような感じでしょうか。
上記のいくつかについて説明しましょう。
set psdir は PostScript prologue ファイルの置き場所の指定のために 新設されたコマンドです (需要は多いんでしょうか ?)。 このコマンドによって prologue ファイルの検索順は、 以下のようになりました。
plot "data" using 1:2:xtic( $3 > 10. ? "A" : "B" )
従来は、HTML のドキュメントは latex2html で作るようになっていたのですが、 それはコメントアウトされて、デフォルトでは TeX4ht を使うようになりました。 texinfo 経由で HTML ドキュメントを作る方法もあるのですが (それもコメントアウトされている)、 今回の変更は開発者側で latex2html での変換が失敗したこと、 latex2html が長くメンテナンスされていないこと、 が理由だとされています。
しかし調べてみると、開発者側で latex2html での変換が失敗したのは、 どうやら latex2html の設定を正しく行っていない (TeX を新しくして latex2html をその変更に合わせていないみたい) という状況のようですし、 「長くメンテナンスされていない」という批判も 最新版の latex2html-2008 を知らないだけのようですから、 latex2html を非難するには少し筋が違うように思います。
ただ、最近の英語圏での LaTeX の傾向 (デフォルトの LaTeX は pdfLaTeX に置き換わっている) からすると前者はある意味仕方がないことかもしれません。 また後者も、latex2html-2008 は latex2html-2002-2-1 から実質的には修正、改良は何も行われておらず、 バージョン名とライセンスが変わっただけなので、 「長くメンテナンスされていない」というのもハズレではありません。 よってそれはそれでしょうがないのかなと思います。
長く報告をためると、これを書くだけでかなり精力を使うので、 次回はなるべくためないようにしたいと思いますが、 うまくいくかどうか...
以前、awk を用いて円グラフを描く例を以下で紹介しました。
最近 CVS 版 (4.5) の with circle で、扇形を描くための開始角、 終了角指定が実装されたので、 これを利用すると gnuplot で直接円グラフが書けそうです。 それを実験してみたものを紹介します。
例えば以下のようなデータファイル data1 を円グラフにすることを考えます:
中国史物 301 列目は項目名、2 列目がその全体の割合 (%) を表しているとします。 なお、これは合計して 100% になっていませんので、 「その他」も後で追加することにします。
推理小説 30
SF 10
科学関係 15
ルポ 5
CVS 版 (4.5) の with circle では、データから以下の 5 列を取得して 扇形を描くことができるようになっています。
(中心の x 座標):(中心の y 座標):(円の半径):(開始角):(終了角)さらに lc variables とすれば、 第 6 列目の値を色指定と見てその扇形をその色で塗り潰すことができます。
よって簡単に考えると、例えば以下のようにやれば良いように見えます。
set style fill solid 1.0 border rgbcolor 'black'中心の座標は (0,0)、半径は r=8 と固定し、開始角は a として保存し、 その項目のパーセントの値を 3.6 倍することで角度に直して、 開始角に加えた値を終了角としています。 色も n を使って一つずつ増やしていますが、 これは ($0+1) としても同じです。 しかし、こうすると以下のようなグラフになってしまいます。
set xrange [-10:10]
set yrange [-10:10]
unset key
unset tics
set size square
r=8
n=0
a=0
plot 'data1' using (0):(0):(r):(a):(a=a+$2*3.6):(n=n+1)\
with circles lc var
見てわかるように、0 度、すなわち x 軸の正の方向から始まって、 反時計回りに進んでいってしまっていますが、 通常の円グラフは、90 度 (y 軸の正の方向) から始まって、 時計回りに進んでいきますので、そのように直してみましょう。 それには、上のスクリプトの最後の 3 行の、 a の初期値を 90+360 にして、plot の using の第 5 列目の 「a=a+$2*3.6」の部分を「a=a-$2*3.6」に変えれば良さそうな気がしますが、 実際には以下のようになってしまいます。
ほぼ全体を覆っている水色は最後の項目なのですが、 むしろ紫の小さい部分 (最後から 2 番目の項目) が本来の水色の部分です。 つまりこれは、with circle の扇形が開始角から終了角までを 「必ず反時計回りに描いている」ということを意味していて、 角の大小には関係ないようです (よって初期値も 90+360 とする必要はなく、 単に 90 でよい)。
ということで、開始角を小さい角にするために、例えば以下のようにします。
a=90
plot 'data1' using (0):(0):(r):(p=$2*3.6,a=a-p):(a+p):(n=n+1)\
with circles lc var
先に $2 の値を角度に直したものを p とし、a-p から a までを描くために、 先に a=a-p としてそこから a+p までを描くようにしています。
さて、次は欠けている部分ですが、これはせっかく n を使っているので、 次のように plot を追加して次の色で塗ってみましょう。
a=90
plot 'data1' using (0):(0):(r):(p=$2*3.6,a=a-p):(a+p):(n=n+1)\
with circles lc var,\
'' using (0):(0):(r):(90):(a):(n+1) every ::0::0\
with circles lc var
これで円グラフは完成です。 しかし、これでは各扇形が何を示しているのかわからないので、 key を使って色見本を作らなければいけません。 gnuplot は key の見出しも「title columnhead(j)」という形式を使って データから取得することはできるのですが、 これはあくまで「データの先頭行の各列を使用する」という機能であって、 「各行から文字列データを取ってそれを title とする」という機能ではありません。
よって仕方がないので、 各項目名を先頭行に持つようなデータを awk などで作ることにします。 それを利用すればなんとか key エントリを作ることができます。 それも合わせて完成したのが以下のスクリプトです。
set style fill solid 1.0 border rgbcolor 'black'
set xrange [-10:10]
set yrange [-10:10]
set key out font "hoge,12"
unset tics
set size square
r=8
n=0
a=90
# 以下で、「その他」も含めた項目名を 1 行目に並べて、
# 2 行目に 1 だけ持つデータを作成
! awk '{printf "%s ",$1}END{print "その他"; print 1}' data1 > data2
plot 'data1' using (0):(0):(r):(p=$2*3.6,a=a-p):(a+p):(n=n+1)\
w circles lc var not,\
'' using (0):(0):(r):(90):(a):(n+1) every ::0::0\
w circles lc var not,\
for [j=1:n+1] 'data2' using 0:(1/0) w l t columnhead(j) lw 4 lt j
! で始まる行は、gnuplot スクリプト内部から awk を実行して data2 を作成するためのものです。 そしてその data2 を、key を生成するためだけに plot for を使って無意味な値 (1/0) のグラフを linewidth 4、 linetype j で描いています。 なお、data2 は項目名が並んだ 1 行だけだと描画してくれませんので、 「1」だけからなる 無意味な 2 行目も追加してあります。
また、それまでの unset key を set key out にしていますので、 円グラフの方の描画には not (= notitle の省略形) を追加して key を生成しないようにしています。 上のスクリプトでは set key out にフォント指定もしていますが、 出力形式毎に適当な日本語フォントを指定しないと文字化けするでしょう。 上のサンプルでは、gif terminal で IPA フォント (TrueType font) を使用しています。
この with circle で扇形が書けるようにしたのは、 このような円グラフを書くことを強く意図したものではないかと思いますので、 今後、描画にしてもタイトルにしても、上のようにしなくても もう少し易しくできるようにすべきなんではないかと思います。
(cf. 「情報やメモ (02/02 2015)」)
「情報やメモ (02/20 2010)」 に書いた、2 ちゃんねるの質問の 「3 次元データを y 軸、または x 軸のみ線でつなぎたい」についてですが、 陰線処理を使用してもよいのならば次のような解もあります。
陰線処理 hidden3d には、trianglepattern というオプションがあり (gnuplot-3.7 以降)、 これによってどの線を表示するのかが分かれます。 これはビットパターンになっていて、 0 ビット目が水平方向の表示をする/しない、 1 ビット目が垂直方向の表示をする/しない、 2 ビット目が対角線の表示をする/しない、 を表します。実際には曲面が三角形に分割されて処理されるので、 対角線とはその斜辺を意味します。
よって trianglepattern 1、あるいは trianglepattern 2 で水平方向のみ、 垂直方向のみの線のみが表示された曲面を作ることができます (デフォルトは trianglepattern 3 で縦横)。
set term gif size 480,360
set xlabel 'x'
set ylabel 'y'
set xrange [-3:3]
set yrange [-3:3]
set view 30
# trianglepattern 1 のサンプル
set hidden3d trianglepattern 1
set isosample 500,25
set out 'hd3d-tr1.gif' splot sin(x*x+y*y)/(1+x*x+y*y)
# trianglepattern 2 のサンプル
set hidden3d trianglepattern 2
set isosample 25, 500
set out 'hd3d-tr2.gif'
replot
# ついでに trianglepattern 7 (全部の線を描画) のサンプル
set hidden3d trianglepattern 7
set isosample 25, 25
set out 'hd3d-tr7.gif'
replot
set out
上記のサンプルの画像:
trianglepattern が 1 や 2 の場合は、やや曲面の裏側に当たる部分 (緑色の部分) も表示されていることがわかります。 この裏側の線を消したければ、 もう少し上の方から見るように角度を変えるとか、 あるいは offset オプションを使って裏側の曲線を見えなくする (表が linetype 1 の場合は offset -3 等) といいかもしれません。
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
3 次元データを y 軸、または x 軸のみ線でつなぎたい、 という質問がありました (733)。
「y 軸」というのは、多分「y 方向」という意味だと思いますが、 回答はついていませんでしたがこれはデータの形式や every などで制御できます。
help splot datafile で参照できますが、 splot ではデータに 1 行の空行で区切られたデータブロックを 一つの折れ線で結びますが (例えば x 方向)、 その各データブロックのデータ数が同じ場合は、 各データブロックの対応する点同士を格子状 (例えば y 方向) に線で結びます。
ちなみに、gnuplot の「格子状データ」(グリッドデータ) とは、 すべてのデータブロックの点数が同じことを指していますので、 x, y 座標が本当に「格子状」に並んでいなくてもこれは行われます。 それは例えば次のようなものを試してみればわかります。
set xlabel "x"この場合、それぞれのデータブロックは x 軸に平行な直線ではなく、 x=2 のところで山型に折れていますが、 それぞれのデータブロックは線で結ばれ (P1-P2-P3, P4-P5-P6)、 そしてデータブロックの点数が両方とも 3 なので 対応する点が線で結ばれます (P1-P4, P2-P5, P3-P6)。
set ylabel "y"
splot '-' w lp
1 1 1 # P1 とする
2 2 2 # P2
3 1 3 # P3
1 2 4 # P4
2 3 3 # P5
3 2 2 # P6
e
逆に言えば、「格子状」でないデータの場合には、 この後者の線が結ばれません。 例えば上の例で言えば 2 つ目のデータブロックの点数が 4 点であれば、 1 つ目と 2 つ目のデータブロックの線が結ばれることはありません。
また、データブロック間の空行が 2 行の場合には、 別のデータ (別の index データ) であると見なされるので、 データブロックの点数が同じでもそれらが線で結ばれることはありません。 よってデータを作るとき、 あるいはできたデータを以下のように加工することで目標は達成できるでしょう。 Unix であれば sort や awk などを使ってこのように加工することは それほど難しくありません。 これが 1 つ目の方法です。すなわち以下のようにします。
もう一つの方法は、データの加工を行わずに every で制御する方法です。 今、データは上のように 1 行の空行で区切られたデータだとします。 この場合、以下のようにすれば各データブロックの点を結ぶ線は引かれますが、 データブロック間を結ぶ線は引かれません。
splot 'data' every :::0::0 w lp notitle lt 1,\これは、every で指定した 1 つのデータブロックだけの単独のグラフを、 複数個書いていることになります。
'' every :::1::1 w lp notitle lt 1,\
'' every :::2::2 w lp notitle lt 1
この方法はデータブロックの個数が多いと現実的ではありませんが、 CVS 版の gnuplot (4.5) ならば、splot for を使って以下のようにできます。
splot for [j=0:20] 'data' every :::j::j w lp notitle lt 1
逆に、データブロックには線を結ばず、 データブロック間の対応する点同士の線を結ぶには、 同じ every を使って以下のようにします。
splot 'data' every ::0::0 w lp notitle lt 1,\これは、各データブロックから every で指定した 1 点ずつを取り出した 「格子状データ」を複数個 描画しているわけですが、 これも一応「格子状」データなのでデータブロック間の線 (1 本のみ) が引かれることになります。
'' every ::1::1 w lp notitle lt 1,\
'' every ::2::2 w lp notitle lt 1
ブロック内の点数が多い場合は、 CVS 版の gnuplot (4.5) ならばやはり splot for でできます。
splot for [j=0:30] 'data' every ::j::j w lp notitle lt 1
x の範囲が同じで y の値が離れたデータを一つのグラフで描画したい、 y 軸の途中を省略するにはどうしたらいいか、という質問がありました (734)。
これもまともな回答がありませんでしたが、 例えば以下のような方法が考えられます。
set y2tics
plot sin(x), 10+cos(x) axes x1y2
offy=5
set ytics ( -1, 0, 1, "9" 9-offy, "10" 10-offy, "11" 11-offy )
plot sin(x), 10+cos(x)-offy title "10+cos(x)"
最後の multiplot を使った、かなり大層な例が 「情報やメモ (01/07 2008)」 にも載せてあります。
z 軸のラベルを XY 面に垂直に出したい、という質問がありました (737)。
これも回答がありませんでしたが、 gnuplot-4.2.5 からはできるようになりました。
set zlabel "label" rotate by 90のようにします。 もちろん、文字列の回転が行える出力形式でのみ有効です。
x 軸の範囲を [0:10] にして、グラフは [3:6] の間だけ書きたい、 という質問がありました (740)。
これに対して、? 3 項演算子を利用した場合分けを用いて、 それ以外の範囲では無効値 (0/0) とした関数を作成して そのグラフを書く、という回答がありました (741) が、 別解として、parametric mode を用いる、という手もあります。
set xrange [0:10]
set parametric
plot [3:6] t,f(t)
グラフの背景を黒、前景 (境界や文字等) を白にするには、 という質問がありました (756)。
set object rectangle behind で背景の塗りつぶしを行って、 set border lc rgb 'white' とする、といった回答がありましたが、 これだと xlabel などの文字色は変わりません。
gnuplot-4.2.X (質問者は 4.2.X) では xtics, xlabel などにも textcolor オプションがつきましたので、 とりあえずこれも設定すればよさそうです (set xlabel 'label' textcolor lt -2) が、 4.2.X では key の文字色が変更できません (CVS 版 (4.5) では key の文字色も指定できるようになりました)。
必要な出力形式が書いてなかったのですが、 前景色、背景色を指定できる出力形式もありますから、 それが可能な出力形式ならそれを利用するという手もあります。
set term png x000000 xffffff
gnuplot*background: black(背景色はコマンドラインオプションで -bg black でも可、 文字色は -fg white では不可)
gnuplot*textColor: white
gnuplot*borderColor: white
グラフウィンドウのタイトルバーをクリックして出てくる プルダウンメニューから [Options] を選択し、 [Background] で背景色を黒に、 [Line Styles] の [Border] の設定を白にすることで可能。 または、WGNUPLOT.INI を直接編集して、 GraphBackground, Border を以下のように修正する。
GraphBackground=0 0 0
Border=255 255 255 0 0
関数の描画で「plot f(x)*100」ができるが、 データの描画でも「plot ('data' using 1:2)*100」や 「plot ('data1' using 1:2)*('data2' using 1:2)」 のようなことはできないでしょうか、という質問がありました (766)。
これは、回答 (768,769) もついていたのですが、 using の指定には、「2」という 2 列目のような指定の他に、 () でくくって数式を書くこともでき、 その場合 $2 や column(2) とすることで「2 列目の値」 を用いることもできるようになっているので、最初の 100 倍については、
plot 'data' using 1:($2*100)とすればいいわけです。ただし、() を省略してはいけません。
「plot ('data1' using 1:2)*('data2' using 1:2)」 については回答 (769) に無理とありましたが、 gnuplot では 2 つのデータを同時に開いて並列に処理する、 ということはできませんので、 確かに直接これを行うことはできません。
しかし、Unix であれば paste コマンドとパイプ入力を用いれば可能です。 paste コマンドは、複数のファイルの同じ行を 1 行に並べて標準出力に流すコマンドです。 ただし、gnuplot で正しく処理するためには、 data1 と data2 の 1 列目 (x の値) がすべて同じ、 空行やコメント行の位置も同じ等の制約はあります。
data1 と data2 がいずれも 2 列しかデータを持っていないとすれば、 data1, data2 の 2 列目は、それぞれ「paste data1 data2」 の出力の 2 列目、4 列目になるので、
plot '< paste data1 data2' using 1:($2*$4)でそれが行えることになります。
(cf. 「情報やメモ (02/20 2010)」)
gnuplot では、 ファイルからの読み込みは描画データとしての読み込みしかできず、 ファイルに書かれた数値をパラメータや変数値として読み込むには gnuplot スクリプトの変数値として書いて load コマンドで読まなければいけません。 例えばファイル data に
1.0 3.0 2.0のように書かれている値を関数 f(x,a,b,c) のパラメータの a,b,c の値として使うことは、標準的にはできず、
a=1.0のように書いたデータを load しなければいけません。 しかし、CVS 版の gnuplot (4.3 以降) ならば、 ',' (カンマ演算子) を使って 最初の形式のファイルからパラメータを取得できなくもありません。
b=3.0
c=2.0
f(x,a,b,c)=a*x*x+b*x+c
plot 'data' every ::0::0 using 1:(a=$1,b=$2,c=$3,1/0) not,\
f(x,a,b,c) t sprintf("f(x,%g,%g,%g)",a,b,c)
最初のデータ描画命令は、
every オプションで 1 行目 (every では 0 番目と指定する)
のデータを読むだけで、実際には 1/0 のグラフ描画、
すなわち何も描画しないようにしています。
しかし、using 内でカンマ演算子を使って a,b,c の値を保存しているので、
次の関数描画でその値 a,b,c をパラメータ値として使えます。
タイトル指定をしないと key には "f(x,a,b,c)" と表示されるので、
上の例では sprintf() を使って key には "f(x,1,3,2)" のように
実際の a,b,c の値を表示するようにしています。
しかし、データファイルにパラメータデータが複数行あり、 それに対応する複数の関数描画をしたい場合はやや面倒です。 例えば data が
1.0 3.0 2.0である場合に上の通りにやると、 (a,b,c)=(6.0,7.0,0.0) の最後のパラメータの組に対するグラフ 一つだけが描画されてしまいます。
4.0 5.0 9.0
6.0 7.0 0.0
CVS 版 gnuplot の iteration 描画 (plot for) を利用して、
f(x,a,b,c)=a*x*x+b*x+c
plot for [j=0:2] 'data' every ::j::j
using 1:(a=$1,b=$2,c=$3,1/0) not,\
f(x,a,b,c) t sprintf("f(x,%g,%g,%g)",a,b,c)
とすると良さそうに感じるかもしれませんが、これでも結果は同じです。
つまり、plot の for の部分は , で切れてしまって
データ描画にしか効かないので、
関数描画部分は for の対象にならないのです。
ということで、plot for をあきらめ、 パラメータデータの行数分だけ描画命令を出すように以下のようにしてみると、 なぜかうまくいきません。
f(x,a,b,c)=a*x*x+b*x+c
j=0
plot 'data' every ::j::j using 1:(a=$1,b=$2,c=$3,j=j+1,1/0) not,\
f(x,a,b,c) lt j t sprintf("f(x,%g,%g,%g)",a,b,c),\
'' every ::j::j using 1:(a=$1,b=$2,c=$3,j=j+1,1/0) not,\
f(x,a,b,c) lt j t sprintf("f(x,%g,%g,%g)",a,b,c),\
'' every ::j::j using 1:(a=$1,b=$2,c=$3,j=j+1,1/0) not,\
f(x,a,b,c) lt j t sprintf("f(x,%g,%g,%g)",a,b,c)
これは、カンマ演算子に j=j+1 を追加し、
every オプションで j+1 行目のデータを a,b,c に保存するようにしています。
これを実行すると、実は key には正しく
"f(x,1,3,2)", "f(x,4,5,9)", "f(x,6,7,0)"
とそれぞれの色の線が表示されるのですが、
グラフは最後の 1 本しか出ません (出ていないように見えます)。
よく調べてみると、どうやら実際には f(x,6,7,0) を lt 1, lt 2, lt 3 で
3 回重ねて書いているようです。
つまり title の方には a,b,c が適切に渡っているのに、
関数描画の際に a,b,c が適切に渡っておらず、
最後の a,b,c の組が渡されているような感じです。
ソースで確認したわけではありませんが、 これは plot で複数の描画を指定した場合、 実際のグラフ描画の際には関数描画はスタックにとり分けて、 データ描画とは別に関数描画は最後にまとめて描いているかのように見えます。
ということで、関数描画を特殊ファイル名 '+' による 疑似データファイルでの描画に変更すると期待通りに表示されました。
f(x,a,b,c)=a*x*x+b*x+c
j=0
plot 'data' every ::j::j using 1:(a=$1,b=$2,c=$3,j=j+1,1/0) not,\
'+' using 1:(f($1,a,b,c)) lt j
t sprintf("f(x,%g,%g,%g)",a,b,c),\
'data' every ::j::j using 1:(a=$1,b=$2,c=$3,j=j+1,1/0) not,\
'+' using 1:(f($1,a,b,c)) lt j
t sprintf("f(x,%g,%g,%g)",a,b,c),\
'data' every ::j::j using 1:(a=$1,b=$2,c=$3,j=j+1,1/0) not,\
'+' using 1:(f($1,a,b,c)) lt j
t sprintf("f(x,%g,%g,%g)",a,b,c)
しかし、もちろんこれはパラメータファイルの行数が大きくなると
あまり実用的ではありません。
多分 multiplot と reread を利用して最初の形の描画を必要なだけ
繰り返す方法でも同様のことは実現できそうに思いますが、
key の表示をずらすのは面倒かもしれません。
gnuplot 自体を改良して、 plot for で複数の描画を対象とするようにするか、 パラメータファイルからパラメータを取得して関数描画に使えるようにするか、 という方法も考えられますが、 前者は誰かが検討していたんだけど面倒な問題があって 実装はされてなかったように思います。 後者もどんな風に実装するかを考えると、 従来の gnuplot の仕様とはだいぶ変わった形なのでかなり面倒な気がします。
(cf. 「情報やメモ (04/08 2011)」)
「情報やメモ (12/21 2009)」 で紹介した、set term win mono の問題を修正するパッチですが、 とりあえず本家の CVS 版に採用されたようです。 問題がなければ、4.4 にも採用されるそうです。