ページが長いので「しおり」の仕組みを用意してみました。
「しおり用」と書かれた所をクリックしてからブックマークに入れると、
それはページの先頭ではなく、その箇所へのブックマークになります。
(03/03 2006)
「情報やメモ (12/05 2009)」 で紹介した、 win terminal ですべての fill density を実現するパッチですが、 色々間違いがありましたので更新しておきます。 CVS 版 (4.5) 用です。
Win32API を良く理解していないための間違いが色々ありましたが、 まだ間違いがあるかもしれませんので、 自己責任でお使いください。 とりあえず demo はだいたい通るようです。
(cf. 「情報やメモ (04/22 2011)」)
最近 win terminal を少しいじっていて気がついたのですが、 "set term win" には "monochrome" オプションがあるものの、
set term win monoとしてもちっとも白黒になりません。 ソースを見ても一応対応はしてあるようなんですが、 試してみると若干おかしな具合になっています。
plot x
これはどうも、なんらかの初期化のタイミングがおかしいのではないかと思って 調べたところ、次のことがわかりました。
これはどうみてもおかしく、むしろ wgnuplot では一度だけ、 terminal オプションを読み込む前に ReadGraphIni() を実行すべきではないかと思い、 そのようなパッチを作ってみました。
これを当てると、 一応 set term win mono としたものがちゃんと反映されるようになるようです。
ところで、win terminal では mono の方では線種は点線等になりますが、 color の方では点線等が使えません。 この color の方で点線を使う方法についてお知らせします (上のパッチは不要)。 wgnuplot 自身に patch を当てて、 色 (15 種)×線種 (5 種) の 75 通りの linetype を作る、 というのが本当は真っ当なんですが (実際それがすぐにできるようにソースは書いてある)、 ここではエンドユーザでもできる方法を紹介します。 ただし、wgnuplot 4.2 以降が必要です。
まず、wgnuplot が利用する初期設定ファイル wgnuplot.ini を修正します。 そのファイルのありかは、 ウィンドウ上部をマウスクリックして現われるポップアップメニューの "Update" に続いて書かれています。 例えばうちの wgnuplot-4.2.6 の場合は、
「C:\Documents and Settings\[user 名]\Application Data\wgnuplot.ini」のようになっていました。
そのファイルをメモ帳や何らかのエディタで直接編集します。 編集するのは Line[n] の項目で、ここの実線のものをいくつか点線等にします。 win terminal がサポートする線種は 5 種 (0 = 実線、1 = 破線、2 = 点線、 3 = 一点鎖線、4 = 二点鎖線) で、 例えばわかりやすいように (そして多分あまり使わないであろう) Line11 から Line14 の実線設定を点線等の設定に変えます。 "Line[n]=" の後ろには数が 5 つ並んでいますが、 最初の 3 つは color の線の色の RGB、4 つ目が color の線種、 5 つ目は monochrome の線種、となっています。 よって 4 つ目の 0 を Line11 から Line14 までを それぞれ 1,2,3,4 とすればいいわけです。
それを上書き保存した上で wgnuplot を立ち上げて test コマンドを実行すれば 11 から 14 までの線種が 変更されているのがわかると思います。 gnuplot-4.2 以降では、線種と線色を独立に指定できますので、例えば
plot sin(x) lt 12 lc 2とすれば、2 の色 (デフォルトは緑) で線種が 12 (点線) のようになるわけです。 さらにこのように組み合わせた linestyle を設定すれば、 より使い勝手は増すと思います。 win terminal で点線等が必要な場合はお試しください。
(cf. 「情報やメモ (01/06 2010)」)
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
松岡さんから、以下の報告がありました。
CVS 版の MS-Windows 用バイナリの win terminal で、 with steps のグラフの線が key の線とつながってしまうバグがある、 との報告がありました。
調べてみると、実は 1 年位前からあるバグのようで、リリース版で言うと gnuplot-4.2.3 (gp423win32) では起きず、 4.2.4 以降 (4.2.5, 4.2.6 も) では起きていました。 CVS 版では修正されているそうですので、 必要ならば松岡さんのものか角藤さんのものを入手するとよろしいでしょう。
(2088 の記事から始まるスレッド 「with steps のバグ?」)
CVS 版 gnuplot の EPS 出力を LaTeX に貼り込んで ps2pdf で PDF で変換すると、 PDF のビューワソフトによってはグラフ中の文字が抜けたり、ソフトが落ちたりする、 という報告がありました。
実は、元々は三重大の奥村先生が運営しておられる TeX Q&A 掲示板 の以下の記事を見て、それでこちらの Q and A で詳細を報告してください、 と振ったものでした。
terminal の設定を
set term postscript eps "GothicBBB-Medium-UniJIS-UTF8-H"
のようにしていて、
Linux (Fedora10) で ps2pdf すると、
Linux および MS-Windows 上の Adobe Reader ではちゃんと表示でき、
Linux 上の Gnome のドキュメントビューアや xpdf では日本語が抜け、
MS-Windows の Foxit Reader はクラッシュする、という症状が起きるそうでした。
MS-Windows 上でフォントを GothicBBB-Medium-83pv-RKSJ-H として EPS を作った場合は、 gs-8.64 の ps2pdf では gs がクラッシュ、8.70 では問題はなく、 Foxit Reader でもちゃんと見えるそうです。
手元でも同じような設定で調べてみたところ、 どうやら gnuplot の問題ではなさそうで、 ps2pdf が UniJIS-UTF8-H のフォントのエンコーディングを カスタムエンコーディングにしてしまって、 それがその日本語フォントを PDF ビューワが認識できなくなってしまう 原因のようでした。
元記事の方は、最終的には EPS ファイルはやめて pdfcairo 出力形式を利用して PDF を直接するようにしたようです ( 「Re: TeX ユーザの集い 2009 アンケート報告書」(53659 番の記事))
(2100 の記事から始まるスレッド 「CVS 版 postscript terminal での日本語使用」)
E.Merritt さんが、4.4 の公開の前に win terminal に残っているバグを何とかしたい、 とメーリングリストに書いていたので、その情報を転送しました。
それに対し、松岡さんからその一部については詳しい解説がありました。
(2105 の記事から始まるスレッド 「win terminal に関するバグ」)
松岡さんから CVS 版のバージョン番号が 4.3 から 4.5 に変更されたとの報告がありました。
さらに、そのスレッドで松田さんから「gnuplot の精義」(山本昌志、カットシステム) という gnuplot 4.2 対応本が出版された、との報告がありました。
早速その本を購入しましたが、 gnuplot-4.2 独自の機能についてもちゃんと触れられていますし、 MS-Windows や Linux での検証も行われていて、とてもいい本だと思います。 ただ、個人的には以下の点がやや残念に思いました。
山本さんは、科学的な情報 (高専での講義や実習の内容) をたくさん WWW ページで (latex2html で) 公開されている方で、 上の 2 番目のものについて出版社にメールを書いたら、 山本さんから丁寧なメールを頂きました。 改訂が行えるときに修正して頂けるそうです。
(2109 の記事から始まるスレッド 「cvs 版のバージョンが 4.5 になりました」)
MS-Windows 用の gnuplot-4.2.6 (gp426win32) で png 出力形式で日本語を出力しようとすると文字化けする、 という質問がありました。
現在の gnuplot では gd ドライバでも適切な TrueType フォントを指定すれば ちゃんと日本語も表示できるのですが、 gnuplot 本家の公開している正式版は、 gd ドライバはデフォルトコンパイルの状態ですので、 png 出力形式のタイトルなどで日本語を使いたい場合は、 その日本語を UTF-8 で gnuplot に与える必要性があります。
MS-Windows 上の UTF-8 を指定して出力できるエディタで gnuplot スクリプトを書けばいいのですが、その際注意が必要なようです。
どうやら UTF-8 には、BOM (Byte Order Mark) というものが 先頭についている形式もあるようで、 MS-Windows のツールは、それが必要なもの、 邪魔なものがあるようなのですが、 wgnuplot は後者でそれがついているとその行を認識できないようです。
その他、emf, PostScript, pngcairo terminal を利用する手もある、 角藤さんの CVS 版ならば png terminal は Shift_JIS でちゃんと日本語が出る (Shift_JIS 対応用の gd ライブラリを使用している) といった報告や、 その際のフォントの指定や gs などの環境設定に関する話題など、 多くの情報が提供されました。
(2118 の記事から始まるスレッド 「png への出力で日本語が文字化けする」)
「スペクトログラム」を表示したい、という質問がありました。 「スペクトログラム」とは、 3 次元データを 2 次元平面に色表現したグラフで、 x 軸は時刻、y 軸は周波数、そして各時刻毎の各周波数の強さを色で 表現したもののようです。
x 座標と y 座標が同じサンプルであるような格子状データならば、 通常はそのようなグラフは「set pm3d map; splot 'data'」で済むのですが、 元記事の方のデータは y 方向のサンプルが少なく、 6 種類の周波数のみしかないそうです (x 座標は 400 種類くらい)。 それだとこれでは、次の 2 つの理由でうまく行きません。
たくさんデータがあれば、多少のずれや面の個数もごまかせるのですが、 6 種類しかないとそうはいきません。 以下では簡単のため、 y 座標が 2 種類、x 座標が 4 種類の以下のデータを使って説明します:
# x 値、y 値、z 値これを、単純に「set pm3d map; splot 'data'」すると、上に述べたように (x,y,z)=(x1,y1,z11), (x2,y1,z21), (x1,y2,z12), (x2,y2,z22) の 4 つのデータに対して、 その z11, z21, z12, z22 の平均値に対応する色を、 xy 平面上の 4 点 (x,y)=(x1,y1),(x2,y1),(x1,y2),(x2,y2) を頂点とする長方形の色として塗りますので、 以下のようなグラフになってしまいます。
0.0 5.0 0.0
0.0 7.0 1.0
1.0 5.0 3.0
1.0 7.0 4.0
2.0 5.0 -2.0
2.0 7.0 -1.0
3.0 5.0 -5.0
3.0 7.0 -4.0
よって、面を平均値ではなく、頂点の値で塗らなければいけないのですが、 それには set pm3d のオプションの corners2color (c1|c2|c3|c4) を使います。 例えば、上のデータの場合は、「set pm3d corners2color c1」とすれば、 以下のようになり、各面の左下角の頂点の値に対応した色で塗られます。 なお、この c1, c2, c3, c4 のどれがどの頂点に対応するかは、 実際にはデータの並び方に依存しますので、 試しながら適切なものを選ぶ必要があります。
しかし、これだと面の数が (2-1)×(4-1) = 3 面しかできないので、 2×4 = 8 つのデータに対応した面を作るには、 データを加工して x, y それぞれ等間隔にダミーのデータを追加して、 (2+1)×(4+1) = 15 個のデータにする必要があります。
# x 値、y 値、z 値z の値は、他の z の範囲の間の値であればなんでも構いません。 これで前のように描画すると以下のようになります。
0.0 5.0 0.0
0.0 7.0 1.0
0.0 9.0 0.0 # ダミー
1.0 5.0 3.0
1.0 7.0 4.0
1.0 9.0 0.0 # ダミー
2.0 5.0 -2.0
2.0 7.0 -1.0
2.0 9.0 0.0 # ダミー
3.0 5.0 -5.0
3.0 7.0 -4.0
3.0 9.0 0.0 # ダミー
4.0 5.0 0.0 # ダミー
4.0 7.0 0.0 # ダミー
4.0 9.0 0.0 # ダミー
これで面の個数も合いましたが、 後は面の位置と軸の目盛りの位置を合わせましょう。 面がデータに対応するのですから、目盛りは面の置くのが自然です。 その場合、xtics, ytics を使って目盛り自体をずらすやり方と、 using を使ってデータの出力位置の方をずらすやり方があります。 前者ならば以下のようにします:
set xtics ( "0.0" 0.5, "1.0" 1.5,
"2.0" 2.5, "3.0" 3.5 )
set ytics ( "5.0" 6.0, "7.0" 8.0 )
splot 'data'
後者ならば以下のようにします:
set format xy "%.1f"
set xtics ( 0.0, 1.0, 2.0, 3.0 )
set ytics ( 5.0, 7.0 )
splot 'data' using ($1-0.5):($2-1.0):3
0.5, 1.0 はそれぞれ x 方向、y 方向のデータ間隔の半分です。
いずれも以下のような出力になります。
なお、「set format xy」は、両者の軸の出力を
完全に揃えるようにしているだけのもので、
あまり意味はありません。
元記事の方のデータは、x 方向には 400 個くらいあるそうですから、 x 方向はデータを追加する必要も、目盛りをずらす必要もないかもしれません。
ダミーデータの追加は、できたデータを awk で処理するなどでもできますが、 元データを C などで作っているのならそちらで追加する方が楽でしょう。
なお、松田さんから、四角のマークの点種を選んで with points で描画し、 その色を z 値として取得する、という強引な裏技も紹介されました。 それは、例えばこんなやつです。
plot 'data' w p pt 5 ps 22 lc palette z
pt 5 が四角を意味し (注: terminal 依存)、
lc palette z が z 値を point の色として使用することを意味します
(実際の松田さんの例は、これとほぼ同等の splot の例です)。
これは、x 座標と y 座標がほぼ同数なら面白い例になっていますが、 元記事の方はそうではないのでちょっとこれだと無理がありそうです。
(2147 の記事から始まるスレッド 「スペクトログラムの表示」)
現在の win terminal では、box の fill solid で指定する密度は 擬似的な処理 (ハーフトーン処理) を行っていて、 そのレベルは 0%, 25%, 50%, 75%, 100% の 5 段階しか用意されておらず、 例えば 0.15 のような密度を指定すると 0% になってしまいます。 多分、古い MS-Windows でも表示できるように そのような対処をしているのだと思います。
これを、他のドライバ同様、色の強度を変更することで すべてのバーセントの密度を実現するようなパッチを作成しました。 src/win/wgraph.c へのパッチです。 こちらでは MS-Windows XP + VC++ 2005 でテストしてあります。
なお、demo を表示させて、Unix の出力と比較するとわかりますが、 MS-Windows で RGB 色強度指定による色と Unix (X Window) の RGB 色には だいぶ違いがあるようです。 MS-Windows 上では win term と emf, png terminal の出力は違いがなく、 その png ファイルを Unix に持ってきて表示させると違って見えるので、 多分それぞれの OS 上のウィンドウシステムの色強度に対応した表示の仕組みが 違っているんだと思います。
また、今回 MS-Windows XP + VC++ 2005 でコンパイルしましたが、 「情報やメモ (05/22 2008)」 と同様に C99 用の修正、およびコンパイルフラグの修正が必要でした。 コンパイルフラグについては、そこと同じように修正し、 C99 用の修正は以下のパッチを当てるととりあえずはコンパイルできるようです。
ただし今回は共用体の初期化だけでなく、 C99 の関数 va_copy() への対処も含まれているのですが、 あまりいい対処ではなく問題が起こる可能性もありますので注意してください。
(cf. 「情報やメモ (12/23 2009)」, 「情報やメモ (04/22 2011)」, 「情報やメモ (01/15 2015)」)
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
tan(x) の∞/-∞ をつなぐ線を消したいという質問がありました (696-699)。
それに対して、set yrange を利用する、という回答がありましたが、 確かに gnuplot の関数描画は、 基本的に samples に対応した点を取って描画を行うだけなので、 以下のいずれかしかないでしょう。
1. は以下のようにやる方法で、多分これが一番簡単でしょう。
set sample 500 ; set yrange [-20:20] ; plot tan(x)
2. は、AWK なり C なりで tan(x) のデータを先に作っておいて データ描画する方法ですが、データに空行が入っていれば、 そこでグラフは一旦切れますからそれを利用します。 つまり、データを AWK なり C なりで作るときに、 π/2 付近の正の大きな数から小さな数に変わるときに一行空行を挟む、 あるいはデータを作った後で正から負に変わるところに空行を AWK などで挟んであげる、 そういうデータを利用する、という手です。 けど、これはそれほど簡単とは言えません。
3. は、場合分け関数を定義する方法です。
f(x) = (abs(tan(x))>20)? 1/0: tan(x)
set sample 500
plot tan(x)
1/0 は無効な値なので、そこでグラフが一旦切れます。
しかし、これは切れる y の値がまちまちなので、
yrange や sample 値をうまく制御しないとあまり綺麗には見えません。
ということは、やはり 1. が一番楽だと思います。
gnuplot よりも matplotlib の方がいい、 という話題があり、そういう 2ch 掲示板も作られたようです (702-709, 714-719)。
matplotlib とは、Python 上でグラフ画像を書くためのライブラリのようで、 Python を使う人には便利なもののようです。 gnuplot にも簡単な制御構文 (if, ループ) はあるのですが、 その点は一般的なスクリプト言語に比べると劣りますから、 もちろん使い慣れているスクリプト言語上のグラフライブラリの方が 優位なところは色々あると思います。 私自身も、普段は gnuplot を対話的に使うよりも、 シェルスクリプト内でヒアドキュメントとして書いたり、 AWK と組み合わせて使うことが多いです。
3 次元データがあるときに、それを単に with dots で表示するのでなく、 個々の点に色をつけたい、という質問がありました。 x,y,z の値を R,G,B に対応させて表示させてみたい、ということです (720-721)。
残念ながら回答はついていませんでしたが、 gnuplot 4.2 のマニュアルには、まさにそんな例が載っています (help lc rgbcolor variable 参照)。
rgb(r,g,b) = 65536 * int(r) + 256 * int(g) + int(b)
splot "data" using 1:2:3:(rgb($1,$2,$3)) with points lc rgb variable
この例では with points ですが、with dots でも可能です。
ただし、with dots では点が小さくて、ほとんど見えない可能性があります。
むしろ set pointsize で点の大きさを調整した上で with points を使った方が
いいだろうと思います。
20 列 100 行の値を描画したいが、 値が 1E-7 から 7 までと広すぎるのでうまく表示されない、 という質問がありました (725)。
描画は set pm3d map のような描画を望んでいるようですが、 確かに値が広くて、 あるところに固まってるとうまく表示されないかもしれません。 具体的なデータがわからないのでなんとも言えませんが、 そういう場合は一般には対数軸を用いるのが普通だと思います。 z 軸、cb 軸を対数軸にして (set logscale zcb)、 set pm3d map とすれば多少は改善する可能性はありそうです。
gnuplot-4.4.0-RC1 が出ました。 その配布物に含まれる NEWS には、以下のように書かれています。
gnuplot 4.2 以降の新しい機能、変更、修正
今まで CVS 版として実装されてきた機能が、 ついに 4.4 で使えるようになります。 4.4.0 の正式リリースももうすぐでしょう。 なお、以後 CVS 版のバージョンは 4.5 ということになります。
(cf. 「情報やメモ (03/14 2010」)
実務上、先日以下のようなデータの散布図を作ろうと思いました。
# x-座標 y-座標 属性これを with points で表示したいのですが、 この 3 列 (カラム) 目の属性毎に点種 (pointtype) を切り替えたいと思いました。
52.0 53.4 3
66.6 56.3 5
35.9 49.8 2
68.3 54.0 6
56.8 53.0 2
41.5 47.1 2
47.3 55.7 4
52.2 46.0 1
39.3 53.6 3
43.2 49.0 3
52.7 52.5 5
46.1 45.3 6
58.6 51.6 2
61.0 54.4 6
36.1 13.8 2
52.5 53.8 4
55.1 58.3 4
しかし with points に関しては、 各点の点のサイズ (pointsize) はデータファイルの列から取得できる (pointsize variable) ものの、 点種をデータファイル列からは直接は取得できるようにはなっていません。 それは、pointtype variable のように実装しても、 key がそれに対応できないから、という理由もあるのでしょう。
よって、属性毎に点種を変えて描画するには、 属性毎に plot を重ねる必要があります。 必要な点種だけを選びだすのは三項演算子を利用すればできます。 例えば以下のような具合です。
# 3 列目が m と等しいならば n 列目、そうでなければ読み捨てる関数 f(n,m) = (column(3) != m)? 1/0 : column(n) set key out set pointsize 3 plot 'data' using 1:(f(2,1)) t 'property 1' w p\ ,'' using 1:(f(2,2)) t 'property 2' w p\ ,'' using 1:(f(2,3)) t 'property 3' w p\ ,'' using 1:(f(2,4)) t 'property 4' w p\ ,'' using 1:(f(2,5)) t 'property 5' w p\ ,'' using 1:(f(2,6)) t 'property 6' w p
これは、gnuplot-4.3 以降の plot for を使用すれば、 以下のように簡単に書くこともできます。
f(n,m) = (column(3) != m)? 1/0 : column(n) titles(n) = sprintf("property %d",n) ltn(n) = (n == 6)? 7 : n set key out set pointsize 3 plot for [j=1:6] 'data' using 1:(f(2,j)) t titles(j) w p lt ltn(j)
なお、上ではついでに、 6 番目の色 (本来は postscript terminal では黄色) が見にくいので、 それを飛ばして 7 番目の色に変えるために ltn(n) という関数を利用しています。
「情報やメモ (10/01 2009)」 で報告した multiplot title にフォントを指定するパッチですが、 めでたく CVS 版の gnuplot に採用されました。
なお、大きなフォントサイズの場合の問題ですが、 これは set title でも同じようなので、 gnuplot ではあまりその辺りまでは考えない、 つまり自前でやれ、ということなのかもしれません。 ただ、set title の場合は、set tmargin を設定するだけで解決するのですが、 multiplot title の場合はそうもいかないようです (set term post)。
これだと multiplot の layout 機能のありがたさがありません。 他の terminal ではまた違った結果になるかもしれませんが、 もう少し調べて、必要ならばバグレポートでも送ってみたいと思います。
最近の gnuplot-4.2.X や CVS 版の gnuplot では、set multiplot に title オプションが使えるようになっていて、 これを使うと、multiplot の複数のグラフ全体 (ページ全体) に 一つのタイトルをつけることができるようになっています。
ところが、この title オプションには font 指定機能がないため、 例によって日本語のタイトルをつけることが面倒になっていて、 以下のいずれかのようにしないといけません。
しかし前者は、他の文字にも日本語フォントが使われてしまうので、 数字などの表示に問題が出る場合があります。 後者は、単純に set label としても ページ上部にはタイトル用の空きができないので、
set label '<日本語タイトル>' at screen 0.3, 0.95
font '<日本語フォント>,<size>'
set multiplot title ''
...
のように空のタイトルを与えて、
そのスペースに set label で書く方法なのですが、
この方法だと厳密には multiplot 内の plot 毎に set label の文字列が
同じ場所に上書きされることになるので、
あまりいい方法ではありません。
ということで、簡単に set multiplot の title のフォントを 指定するパッチを作ってみました。これにより、
set multiplot title '<日本語タイトル>'
font '<日本語フォント>,<size>'
のような指定ができるようになります。
しかし、これはまだ完全ではなく、 大きなフォントサイズを指定するとタイトルが上にはみでてしまいます。 フォントサイズに応じたマージンを空ける方法を知らないことが問題なのですが、 それは開発者にでも聞いてみたいと思います。
(cf. 「情報やメモ (10/08 2009)」)
gnuplot-4.2.6 がリリースされました。 日本語マニュアル も 後で更新しておきます。 gnuplot-4.2.6 の、gnuplot-4.2.5 以降の機能の更新情報を追加しておきます。
「gnuplot version 4.2.6 での新しい機能、変更、修正」
ということで、今回はそれほど大きな変更や新規機能は追加されていませんが、 この 4.2.6 が 4.2 系列の最終版となる予定だそうで、 次期版は今までの開発版である 4.3 を安定版にした 4.4 がリリースされる予定です。
「情報やメモ (03/30 2009)」 に書いた、MS-Windows Vista 上の wgnuplot の件ですが、 MS-Windows Vista 上での wgnuplot のインストールについて書かれたブログを 見つけました
これによると、特に日本語化は問題なくできるようです。 ヘルプは WinHlp32.exe をインストールしただけではだめで、 ブロックを解除とかいうことをやる必要があるようです。
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
「set size ratio -1; set view 80, 50, 1.5」としたら、 gnuplot のバージョンが変わったら表示が変わってしまった、 という話がありました (643,645,650,651)。
確かに、gnuplot-4.0 と gnuplot-4.2 の出力を確認してみると違っています。 これは、「set size ratio -1」を外すと どちらも同じになることからわかりますが、 gnuplot-4.2 の help set size に書いてあることと関係しています。
gnuplot-4.0 以前の set size は、terminal によっては 全体のサイズの制御にも使っているものがあり、 つまり terminal 毎に set size と terminal オプションの size 指定の挙動が統一されていませんでした。 これが gnuplot-4.2 以降統一され始め、 主要な terminal については以下のように改良されています。
この問題もその名残りのようです。 なお、元記事では set view の第 3 引数で 1 より大きい数を指定していますが、 多分これを調整する必要があるでしょう。
これは Linux の問題のようですが、 「Failed to receive messages at scim_bridge_client_read_and_dispatch ()」 のようなメッセージが出る、という問題が報告されました (652,661)。
コンパイルし直したら、というフォローがついていましたが、 以下を見ると、anthy の個人ファイルみたいなものを 見せないようにするといい、という話もあるようです。
「z=(1-2 x y)/(2-x) かつ y=1+1/(2 x)」なる曲線を描かせるには、 という質問がありました (662-664)。
parametric を使えばいいとか、 3 次元空間の曲面上での束縛条件を満足する曲線の表示は parametric とは違うという意見がありましたが、 真に 3 次元空間の曲線ならともかく、 これは y は x の式なのでそれを z の式に代入すれば 単純に z が x の 1 変数関数になるので、 それを plot で 2 次元描画すればいいだけでしょう。
f(x,y)=(1-2*x*y)/(2-x)それとも、z=f(x,y) の 3 次元グラフを書いて、 その曲面上の y=g(x) という曲線を描きたい、 ということなら、回答通り parametric モードで描けます。 この曲線は、x をパラメータとして (x,y,z) = (x,g(x),f(x,g(x))) と 表されるわけですから、例えば次のようにすればいいでしょう。
g(x)=1+1.0/(2.0*x)
plot f(x,g(x))
f(x,y)=(1-2*x*y)/(2-x)最初の u,v,f(u,v) は曲面 z=f(x,y) を描画し、 後ろの u,g(u),f(u,g(u)) がその曲面上の曲線を描画します
g(x)=1+1.0/(2.0*x)
xmin=-1; xmax=2
ymin=0; ymax=3
set parametric
set xrange [xmin:xmax]
set yrange [ymin:ymax]
splot [xmin:xmax][ymin:ymax] u,v,f(u,v) w l 1, \
u,g(u),f(u,g(u)) w l 3
set term png の multiplot で、左右に 2 つのグラフを並べて書いたけど、 右側のグラフが出ない、という報告がありました。具体的には、
set term pngとしていて、cos(x) の方が描画されないということでした (665-667)。
set size 0.5,1
set output 'file.png'
set multiplot
set origin 0,0
plot sin(x)
set origin 0.5,0
plot cos(x)
unset multiplot
unset output
これには、4.3 では大丈夫とか、set origin 0.5, 0 がおかしい、 という回答が来ていましたが、 これも set size の問題と関連しているようです。
こちらでも試してみたのですが、 例えば terminal によっても結果が異なり、 x11 terminal の場合は gnuplot-3.7.3, 4.0, 4.2, 4.3 いずれも 両方のグラフが出力されますが、 png terminal だと確かにバージョンによって左側のみ表示され、 グラフの横幅が半分になります。 この「グラフの横幅が半分になってしまう」ということ自体が、 古い set size の問題であることを意味しています。
しかし、現在の正式版である gnuplot-4.2.5 でもデフォルト値の関係なのか 同じように半分に切れてしまうようで、 解決策の一つとしては terminal option の size 指定をする、 という手があります。ただしこの方法は、 gnuplot-4.0 では set size 自身に問題があるため効きません。 つまり以下のようになります。
では、3.7, 4.0 ではどうにもならないか、というとそうではなく、 実は set size の位置を変えれば解決します。
set term pngのように、set size 0.5, 1 を multiplot の次に書きます。 こうすると、multiplot 前に全体のサイズがデフォルトで確定するので、 multiplot 内のグラフのサイズのみが半分になってくれます。 これなら、gnuplot-3.7, 4.0 でも (もちろん 4.2 でも 4.3 でも) ちゃんと全体の横幅は維持され、2 つのグラフが横に並んでくれます。
set output 'file.png'
set multiplot
set size 0.5,1 # set size を multiplot の後に持ってくる
set origin 0,0
plot sin(x)
set origin 0.5,0
plot cos(x)
unset multiplot
unset output
「情報やメモ (08/19 2009)」 で報告した tgif terminal の pattern fill などに関するパッチですが、 めでたく CVS 版 gnuplot に採用されたようです。
引き続き tgif terminal の話ですが、 現在のコードに追従してない部分の改良などを行って、 以下のパッチを作りました (gnuplot-4.3 用)。
これを当てると以下のようになります。
test コマンドや fillbetween.dem, fillstyle.dem などを試してみると 改善点がよくわかると思います。 point の記号は、他の terminal に合わせて変えてみました。 パターンは、他の terminal と少し違いますが、 tgif に用意されている塗り潰しパターンに対応するものがないものがあったためで、 一応なるべく近そうなものを選んであります。
なお、まだ test コマンドの表示のうち、 Enhanced text と文字列の任意角度の回転はサポートされていません。 文字列の回転は、90度、180度、270度のみサポートされていますが、 任意角度の回転は tgif では可能ですが結構面倒なのでまだ実装していません (FileVerson も上げる必要があります)。 とりあえずは、できたファイルを tgif で開いて手動で回転してください。
また、transparent.dem にある pattern fill の透過性 (set style fill transparent pattern) は、 現在の tgif では容易に行えるのですが、 これも gnuplot の tgif.trm に実装するには FileVersion を 37 以上に上げる必要があり、 それにともなって他の部分も色々修正する必要がありますし、 tgif-3 などの古い tgif では見れなくなるのでやっていません。 これも tgif-4.X で開けば、透過型の塗り潰しにすることは容易に行えますので、 とりあえずはあまり問題はないのではないかと思います。
(cf. 「情報やメモ (08/20 2009)」)
「情報やメモ (08/16 2009)」 で報告した tgif terminal の rgb color を使えるようにするパッチですが、 めでたく CVS 版 gnuplot に採用されたようです。
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に、tgif terminal では rgbcolor が使えない、という質問がありました (660)。 例えば「lc rgb "#590000"」のような指定をすると、
smooth palette in tgif: available 128 color positions; using 128 of themと言われてうまくいかないそうです。
調べてみると、Tgif terminal は palette はサポートしているものの、 確かに rgbcolor をサポートしていないようでした。 とりあえずやっつけ仕事で以下のパッチを作ってみました (for gnuplot-4.3)。 これで一応そのような指定も行えるようになるようです。
なお、上のパッチはついでに現在は意味がない古いコード (白黒モードと線幅に関するもの) の削除も行っているのですが、 白黒モードに関する処理が、 現在の gnuplot のコードにやや追従していないような気もしますので、 また直さないといけないかもしれません。
(cf. 「情報やメモ (08/17 2009)」)
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
松岡さんから、以下の報告がありました。
MS-Windows 版 wgnuplot のメニューにある Open でデータを開くと、 "invalid command" と言われる、という質問がありました。
確かに、wgnuplot の File メニューには、Open (開く) というものがあって、 C などでプログラムを書く人には、 「これはデータを開くという意味かな」と勘違いする人もいるようですが、 実はこの Open は、gnuplot の "load&qult; 命令を実行するコマンドで、 よって「データを開く」のではなく、 「gnuplot の命令スクリプト」を開くためのものです。 ちょっとその辺りは、初心者には紛らわしいのかもしれませんから、 訳を考え直してみる必要もあるでしょうか。
(2000 の記事から始まるスレッド 「データファイル読み込み時の invalid command」)
ソートされていないデータの等高線描画を行いたいが、うまくいかない、 という質問がありました。 元記事の方とのやりとりの結果、 データがどのようなものかわかったので解決しましたが、 確かにこれは助言なしでの解決は難しいかもしれません。 結論から言えば、格子状でないデータ (不等間隔や非整列データ) の等高線描画のためには、dgrid3d のパラメータの調整を行う必要があります。
gnuplot でデータの等高線 (contour) を描画する場合は、 データが格子状のものでなければならないのですが、 今回のデータはそうではなく、 x 座標や y 座標が単調でも等間隔でもないので、 そこから格子状データを「作る」ために dgrid3d を行う必要があります。
元記事の方は、単に "set dgrid3d" としたようですが、 この場合 dgrid3d のデフォルト値である "set dgrid3d 10,10,1" が使われ (help dgrid3d 参照)、 この場合、x 方向、y 方向が 10 サンプルずつの格子、 重み計算用のノルムが 1 というものになります。 しかし、元のデータは x 座標が 0.2600 から 26.2875 y 座標が 0.2750 から 11.8000 という 1100 行超のデータですから、 サンプル数が 10x10 では粗すぎです。 また、ノルムの値が小さいと平滑化作用が強いので、 データ点数が多い場合はノルムを多少大きくした方がいいでしょう。
松田@東京電機大 さんは 適切そうな dgrid3d 30,60,4 という解を与えておられましたが、 私が思うに、いきなり等高線を書かせると何が起こっているのかわかりませんから、 まずは set contour なし (set view map もなし) で dgrid3d の結果の曲面を splot で描画させるといいのではないかと思います (デフォルトの "set dgrid3d" で何が起きていたのかも 気がついたのではないかと思います)。 その上で、その曲面が適切なものになるように dgrid3d のパラメータを調整してから 等高線を書かせたらよいのではないかと思います。
なお、元記事の方は、"set view 0,0" を使っておられましたが、 "set view map" と "set view 0,0" には、 すぐ下に書くように微妙に違いがあります。 等高線を書く場合は "set view map" がいいでしょう。
(2010 の記事から始まるスレッド 「3 次元のデータプロットについて」)
z=f(x,y) の関数を真上から見たときの床面の xy 平面を正確に正方形にしたいが "set size square" がうまくいかない、という質問がありました。 これには、次のような 2 つの follow がつきましたが、少し注釈が必要です。
まず、最初の set view equal xy は、 正確に言えばこれは底面を「正方形」にするためのものではなく、 x 軸と y 軸の単位長を同じ長さにするためのものです。 よって、xrange が [0:3], yrange が [2:4] なら、 3:2 の比の長方形が書かれることになります。 つまり、"set size square" の 3 次元版ではありません。 よって、この方法で「正方形」を実現するには、 色々な「ごまかし」が必要です。 つまり、元の関数の範囲を同じ幅にするようにスケール変換しておいて、 それぞれの tics の見出しを自前でつける、といったことをしないといけません。
また、後者の「set view map; set size square」は、 一見それと同等そうに見える「set view 0,0; set size square」 ではうまくいきません。 つまり、"set view map" と "set view 0,0" とは違いがあり、 set size の設定は、"set view map" には効くのですが、 3 次元描画の一例である "set view 0,0" には効きません。 この他にも、軸の目盛りの付き方なども違いがあります。 元記事の人もこの「set view 0,0; set size square」 をやってしまったのかもしれません。
(2020 の記事から始まるスレッド 「3 次元プロットの床面」)
with linespoints の点の記号として丸を書く場合、 その中に線を書かない方法は以前 (「情報やメモ (10/16 2008; no.3)」) 紹介しましたが、それと同様の質問がありました。 今回は postscript terminal の場合で、 重ね書きする回答を松田@東京電機大 さんが示しておられますが、 凡例 (key) の方はどうするのか、ということに対して、 これも multiplot を使って重ね書きする超絶技巧を 松田さんが示しておられます。
確かに、gnuplot では描画を重ね書きすることで 色々な状況を実現することができるのですが、 key をそれに合わせることが簡単にはできません。 なにかうまい仕組みを実装できればいいのかもしれませんが、 難しいでしょう。
ただ、元記事では丸を書きたいようだったので、 gnuplot-4.3 ならば、with circles を使って以下のように重ね書きし、
set style fill solid 1 border lt 4 # 中は塗り潰し、境界は線種 4key の方は "set object circle" を使って重ね書きできるので、 multiplot を使うよりは状況はましだと思います。
plot 'data' w l lt 3, '' using 1:2:(0.05) w circle lt -2 notitle
# 半径は 0.05、中は無色 (-2) で塗り潰し
(2024 の記事から始まるスレッド 「データのプロット」)
以下の松田@東京電機大 さんのサイトにある方法では EPS の漢字が化ける、 という報告がありました。
元記事の方は MS-Windows XP なので、 上のサイトに書いてある Unix 流のやり方ではだめで、 PostScript フォント名を変えないといけません。 "Kochi-Mincho-EUC-H", "Ryumin-Light-EUC-H" を "Ryumin-Light-RKSJ-H" に、 "Kochi-Gothic-EUC-H", "GothicBBB-Medium-EUC-H" を "GothicBBB-Medium-RKSJ-H" に変える必要があります。 できる PostScript ファイルを参照するソフト (Gsview とか) の設定によっては "MS-Mincho-RKSJ-H"、 "MS-Gothic-RKSJ-H" でも いいかもしれません。
なお最後の EUC-H や RKSJ-H はエンコードと組方向を表していて、 EUC は EUC-JP, RKSJ は Shift_JIS を表し、H は横組み、V が縦組みを表します。 Shift_JIS の場合は 83pv-RKSJ-H (83pv は Apple Mac 用文字セット) などをさらに付ける場合もあります。
(2036 の記事から始まるスレッド 「EPS画像の漢字表示」)
set contour ; set view map で等高線を書かせた場合、 データがない場所もグラフが書かれてしまうのですが、という質問がありました。 これは、gnuplot では仕様なので仕方がありません。 gnuplot では等高線は格子状データに対してしか書けませんから、 データがない場所があっても、 それを dgrid3d すればそこにデータが埋められてしまいます。
これに対して、松田@東京電機大 さんから、 作られた画像のうちデータのない部分を黒く塗りつぶすような 見事なサンプルが投稿されました。
これは一応は無難な方法で、逆に言えば gnuplot ではこれが限界ですが、 データのないところを dgrid3d でデータを作ってしまって等高線を書かせるのは 本当はあまりよくないような気がします。 本来は、元データの方でデータのないところを無効なデータ値 (例えば負の大きな値) にしたような格子状データを作成した上で、 それを gnuplot にかけるのがいいのだろうと思います。
(2052 の記事から始まるスレッド 「データのプロットエリアについて」)
timefmt で 1 秒未満の単位の時刻が含まれるデータを表示するには、 という質問がありました。
gnuplot の timefmt での最小単位は整数秒なので、 基本的に 1 秒未満の単位の時刻は timefmt では扱えません。 しかし、逆にそのような時刻を扱わなければいけない場合は、 分 (minute) や時間 (hour) の桁には本質的には意味がありません。 例えば 1/10 秒が最小単位だとすると、 横軸が秒の桁を越えて分の桁になるには 600 刻みが必要になります。 どのような出力形式であっても、グラフの解像度からして 多分 600 ドットもあれば十分でしょうから分の桁は必要ないわけです。
つまり、そのようなグラフの xrange では分や時間 (hour) はほとんど変化ないので、 時間はそういう表記をする必要がないだろう、 必要があるなら自動処理ではなく、自前でやれば十分であろうということです。 だから、timefmt を使わずにその秒数だけ取りだして x 座標とすればいいわけです。 もちろん、set format x や set for [...] xtics (要 gnuplot-4.3) を使えば それなりに工夫した xtics を作ることも可能でしょう。
(2059 の記事から始まるスレッド 「timefmt での %S」)
CVS 版での Qt terminal への対応の報告を行ったところ、 それに wakakumo さんが応じて下さって、 早速リソースの日本語への翻訳と本家への投稿を行ってくださって、 それがすぐに採用されました。 おかげで、現在の CVS 版の Qt terminal は 日本語環境ではデフォルトで日本語メニューが出るようになっています。 どうもありがとうございます。
(2075 の記事から始まるスレッド 「Qt terminal」)
前回の報告 (03/19 2009)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
相変わらずだいぶ怠けていたため、かなりたまってしまっていますが、 今回の目玉は、マウスホイールへの対応、qt terminal の新設、 gd ドライバ (gif/png/jpeg terminal) の fontconfig 対応でしょうか。
マウスホイールによる動作は、以下のようになっています。
qt terminal は、wxt terminal 同様の マルチプラットホームライブラリ Qt (要 Qt 4.5 以降) を利用した 対話型ターミナルで、 オプション等も wxt 同様です。 しかも、早々に wakakumo さんがリソースを日本語訳してくれたおかげで、 デフォルトで日本語メニューが利用できます。 日本語処理も Qt ライブラリがやってくれますので、 fontconfig で日本語フォントを指定すれば普通に日本語出力が行えます。 ただ、うちの環境ではレンダリングが wxt に比べるとやや見劣りします。 アンチエイリアスが効いていないようなのですが、 ディスプレイやグラフィック性能のせいでしょうか。
(cf. 「情報やメモ (02/26 2010)」)
「情報やメモ (07/24 2009)」 で報告した gettext 対応を本家に送ってみたのですが、 変更点が多すぎる、とのことでそのうち半分を、 int_error() 等を変更することで削除したら、 という提案に基づいて修正しました。 最近導入された qt terminal 用の修正も含まれています。
なお、これでもまだ変更点が多い (fprintf(), fputs() 等) ので、 それを何とかしないと本家には採用されない可能性があります。 どうしようか、今少し頭をひねっています。
gnuplot の GNU gettext 対応なるものをやってみました。 これで、エラーメッセージ等のメッセージの多くが 日本語で出力されるようになります。
上記ファイルには、CVS 版 gnuplot に対する GNU gettext 用の差分と、 日本語のメッセージカタログファイルが入っています。 ただ、configure や Makefile はいじっていませんので、 上記のパッチを当てたものをコンパイルするときは、 src/Makefile の CFLAGS に
-D_GNU_GETTEXT_ -DLOCALEDIR=$hoge -I$fuga/includeを追加します。 ここで、$hoge はメッセージカタログをインストールするディレクトリ (例えば /usr/local/share/locale など)、 $fuga/include は置かれている libintl.h があるディレクトリです。 さらに、LDFLAGS (AM_LDFLAGS でもよい) に
-lintl -L$fuga/libを追加します。
コンパイルが終わったら、 上記アーカイブファイルに含まれるメッセージカタログを インストールします。
mkdir -p $hoge/ja/LC_MESSAGES $hoge/ja_JP.UTF-8/LC_MESSAGESこれで、各種メッセージが日本語になるはずです。 例えば起動時のメッセージは以下のような具合です。
cp po/ja.gmo $hoge/ja/LC_MESSAGES/gnuplot.mo
cp po/ja-utf8.gmo $hoge/ja_JP.UTF-8/LC_MESSAGES/gnuplot.mo
% ./gnuplot G N U P L O T バージョン 4.3 パッチレベル 0 最終更新日 June 2009 システム: SunOS 5.9 Copyright (C) 1986-1993, 1998, 2004, 2007-2009 Thomas Williams, Colin Kelley, その他大勢 オンラインリファレンスマニュアルを見るには `help` と打ちます。 gnuplot FAQ は以下にあります http://www.gnuplot.info/faq/ コメントや質問は <[email protected]> へ送ってください バグや提案は <[email protected]> へ送ってください terminal を 'x11' にセットします gnuplot>なお、やっつけ仕事なので、まだだいぶ不十分なところはあると思います。 何かありましたらご連絡ください。
また、これは GNU gettext 用で、Solaris の gettext には対応していませんので 注意してください (うちは Solaris 9 + GNU gettext-0.16.1 で動作確認)。
(cf. 「情報やメモ (08/05 2009)」)
現在の gdlib (2.0.29 あたり以降) は fontconfig にも対応しているようですが、 それへの対応が、最近の gnuplot-4.3 の gd.trm で行われました。
ただ、gd.trm ではその部分は gdlib の 2.0.36 以降を要求するような コードになっているのですが、 一応 gdlib の 2.0.35 でもそこを修正すれば動くようです。 2.0.36 以降でないとどういう問題が起きるのかはわかりません (そもそも 2.0.36 はまだ RC1 版しかでてないようです)。
set term pngのような fontconfig のフォント名で 正しく日本語が出力されることを確認しました。 ただし従来通り、EUC-JP 等の漢字コードを通すには、 -DJISX0208 でビルドした gdlib が必要で、 そうでない場合は日本語を UTF-8 で与える必要があります。
set out "file.png"
set title "日本語" font "IPAMincho,17"
plot sin(x)
set out
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます (URL が変わっていたので、 最近の投稿があるのに気がついていませんでした)。
マウスで特定の line をトラッキングする機能はないか、 という質問がありました (583)。
例えばこういうもの、というのを見てみたら、 複数の曲線のグラフが重ねて書かれている場合に、 マウスカーソルを合わせることで、 特定のグラフのみをクローズアップさせるような機能のことのようです。
対話型 terminal では、あれば面白い機能かもしれませんが、 現在の gnuplot のグラフの書き方からすれば実装は難しいような気がします。 gnuplot は、基本的にどの terminal でもほぼ同じ仕組みで出力することで、 単純に汎用な出力形式に対応する、という思想を取っています。 だから、そのような機能を実装しようとすると、 対話型 terminal だけグラフの書き方を現在とは だいぶ変えないといけないような気がします (各グラフ毎に描画フレームを設定し、 特定の状況の場合に特定のフレームをハイライト表示させる等)。
とにかく、現在の gnuplot では、 そういう機能を実装させるのはだいぶ難しそうです。
eepic 出力でマーカを変えるには、という質問がありました (589)。
with points の eepic でのマーカは、 pt (pointtype) で多少は変えられ、順に
「$\Diamond$, $+$, $\Box$, $\times$, $\triangle$, $\star$, \circle{12}, \circle{18}, \circle{24}, \circle*{12}, \circle*{18}, \circle*{24}」のように変わるようですが、 確かに自分独自のものにしたいと思うこともあるかと思います。
これは、通常の方法ではできません (質問者は出力をエディタで修正しているようです) が、 例えば gnuplot-4.3 (CVS 版) で、 「情報やメモ (09/08 2007)」 で説明した方法を使えばできなくはありません。
set term eepic
set out 'file.tex'
set sample 80
plot '+' using 1:(sin($1)):('$\\otimes$') with labels
set out
with labels を使うために疑似ファイル '+' を使っていますが、 これは gnuplot-4.3 でないと使えません。 描画するのが関数でなくてデータであれば、 '+' を使わなくてもそのまま with labels で using の 3 番目の引数に 使いたいマーカを書けばいいだけなので、 gnuplot-4.2.X でできます。
set term eepic
set out 'file.tex'
plot 'data' using 1:2:('$\\otimes$') with labels
set out
けど Unix なら、sed を使えばできたファイルの置換も面倒ではないので、 それでもいいかなと思いますね。
set term eepic
set out 'tmp.tex'
plot 'data' using 1:2 with points
set out
! sed 's/\\Diamond/\\otimes/g' tmp.tex > file.tex
もちろん、MS-Windows でも (そこで動く sed を使えば) 同様のことはできると思います。
グラフの凡例 (key) のタイトルを左揃えにするには、という質問がありました (590)。
回答としては、"set key reverse" というものがついていましたが、 それはサンプルと文字列を左右入れ替えるもので、正しくは、
set key Leftです ("left" でなく "Left")。 これは gnuplot-3.7 から使えます。
set term win でプロットしたグラフをクリップボードに、 メニューで対話型でやるのではなくて、 gnuplot スクリプトから取り込むことができるか、という質問がありました (593)。
残念ながら、win terminal に限定した gnuplot コマンドがないので、 gnuplot スクリプトからクリップボードに入れることはできないようですが、 ソースを見ると、 それをあるキー (Ctrl-Insert とか) に割り当てらるように改変することは それほど難しくなくできそうな気がします。 それができれば、メニューから "Copy to Clipboard" を選択するよりは楽になるかもしれません。
データの減少部分の線分の色を変えたい、という質問がありました (594)。 これは、例えば、
1 2というデータのときに、x の [1:3] と [4:5], [7:8] の範囲は赤で、 [3:4] と [5:7] の範囲は青で書く、といったことを意味しているようです。
2 3
3 5
4 3
5 6
7 2
8 2
質問者は自己解決したようですが、それなりに面倒 (で面白そう) な気がします。 例えば以下のような方法が考えられます。
1. は例えば以下のようにする、という方法です。
awk '(NR==1){y=$2;print;next} {if(y>$2) print "";print;y=$2}' data > data1awk を用いて、 data の減少している部分 (y は前の行の y の値) に 空行を 1 行挟んだデータ data 1 と、 data の減少していない部分に空行を 1 行挟んだデータ data 2 を作っています。 これにより、data1 は
awk '(NR==1){y=$2;print;next} {if(y<=$2) print "";print;y=$2}' data > data2
1 2data2 は
2 3
3 5
4 3
5 6
7 2
8 2
1 2となります。 gnuplot は空行があると、そこの線はつながなくなるので、 これで with lines で plot すれば 増加部分、減少部分のみが描画されることになります:
2 3
3 5
4 3
5 6
7 2
8 2
plot 'data1' w l lt 1, 'data2' w l lt 3
2. は、例えば以下のようにする、という方法です。
awk '(NR==1){y=$2;print $0,1;next} {if(y>$2) d=2;else d=1;y=$2;print $0,d}' data > data3これで、前の行よりも y の値が小さい行には 2 が、そうでない行には 1 が、 各行の 3 列目につきます:
1 2 1これを、lc rgbcolor variable (gnuplot-4.2.2 以降が必要) で以下のように描画します。
2 3 1
3 5 1
4 3 2
5 6 1
7 2 2
8 2 1
rgb(a,b,c)=int(a)*65536+int(b)*256+int(c)rgbcolor の色指定は、上の rgb() 関数の値のような 24bit 整数値なので、 それで red (=#ff0000), blue (=#0000ff) を作っています。 lc rgbcolor variable は、3 列目の値を線の色 (24 bit RGB 整数値) として使用する指定なので、 $3 が 1 かそれ以外かでそのような値を返すようにしています。 これは、出力 terminal が color palette に対応している必要があります。 なお、この 3 列目の色は、その点とその一つ前の点を結ぶ線分に用いられます。
red = rgb(255,0,0)
blue = rgb(0,0,255)
plot 'data3' using 1:2:(($3==1)?red:blue) w l lc rgbcolor variable
また、gnuplot-4.3 を使うならば、lc variable も使えます。これは、 3 列目の値を色番号 (linetype) として使用する指定で、 この場合は以下のようにすればいいでしょう。
plot 'data3' using 1:2:(($3==1)?1:3) w l lc variableこれなら、color palette に対応していない出力 terminal でも使えます。
3. は、gnuplot-4.3 の , 演算子を用いる方法ですが、 これを使えば、前の行の値というものを gnuplot 内で使えるので、 awk を使う必要がありません。例えば以下のようにします。
y=0
plot 'data' using 1:2:(d=$2-y,y=$2,(d>=0)?1:3) with l lc variable
d に現在の y の値と前の行の y の値との差が保存され、 それによって線種の色を変えるようにしています。
元記事の人は、色々試しているうちにできたようですが、 上の方法はいずれにせよちょっと考える必要があるように思いますので、 どのようにしてやったのか多少興味があります。
grid を細かい破線 (xtics) と太い実線 (x2tics) で 2 種類同時に書くには、という質問がありました (622)。
残念ながら grid は 2 種類しか書けなくて、それは 主目盛用 ({x,y,z,x2,y2,cb}tics), と副目盛用 (m{x,y,z,x2,y2,cb}tics) となっているので、どちらも主目盛である xtics, x2tics の目盛の grid を別の種類で書き分けることはできません。
無理矢理するとすれば、x2tics に対する grid は設定せずに、 自前で set arrow を使って grid を書く、といった感じでしょうか。
(cf. 「情報やメモ (02/07 2012)」)
「情報やメモ (02/26 2009)」 で、データの最大値、最小値を知ることはできるが、平均値を知ることは gnuplot ではできない、と書きましたが、 CVS 版の gnuplot なら累次評価演算子 (,,...) (cf. 「情報やメモ (08/31 2007)」) を用いてできることに気がつきました。 最大値、最小値も、一度空読みする必要がありますから、 それも含めて例を示します。
以下の例は、データファイル data の 2 列目のデータの最大値、最小値、 平均値を表示します。
set term unknown
sum=0
N=0
plot 'data' using 1:(sum=sum+$2,N=N+1,$2)
ymax=GPVAL_DATA_Y_MAX
ymin=GPVAL_DATA_Y_MIN
print ymax,ymin,sum/N
累次評価演算子 (,,...) は、順次カンマ区切りの式が評価された後で、 式の値としては最後のものが評価されます。 よって、上の plot 命令によって sum に 2 列目のデータの和が、 N にデータの個数が保存されます。 もちろん最大値や最小値をそれによって取得することも可能ですが、 それは GPVAL_DATA_Y_{MAX,MIN} でできるので 上によって最大値、最小値、平均値が取得できます。
なお、最初の「set term unknown」は、データの空読みをするための 空の terminal の指定です。 実は unknown terminal はマニュアルには明記されていないのですが、 出力を生成しない terminal として指定することができます。
さらに、最大値、最小値、平均値も含めてグラフを書くには、 例えば以下のようにすればいいでしょう:
set term push # terminal の保存
set term unknown
sum=0
N=0
plot 'data' using 1:(sum=sum+$2,N=N+1,$2)
ymax=GPVAL_DATA_Y_MAX
ymin=GPVAL_DATA_Y_MIN
set term pop # terminal の復帰
d=(ymax-ymin)*0.2 # 最大値の上と最小値の下の余白
set yrange [ymin-d:ymax+d]
plot 'data' using 1:2 w lp, ymax t "最大値", ymin t "最小値", sum/N t "平均値"
ついでに言えば、この累次評価演算子を使えば、 「情報やメモ (01/08 2009)」 に書いた、データファイルの先頭行の値を各行から引いた値のグラフを描画する 別解を与えることもできます (CVS 版のみ)。
plot 'data' using 1:($0==0?d=$2:1,$2-d) w l
$0 は、2 行の空行がなければ行番号 (0 から始まる) を意味しますので、
?: の三項演算子を使って先頭行の値を d と保存して、
それを $2 から引いたものを y の値として使用しています。
これだと 1 行で済みますし、awk も必要ありません。
gnuplot-4.2.5 がリリースされました。 日本語マニュアル も 後で更新しておきます。 gnuplot-4.2.5 の、gnuplot-4.2.4 以降の機能の更新情報を追加しておきます。
「gnuplot version 4.2.5 での新しい機能、変更、修正」
私は、4.3 CVS 版に取り入れられた新規の機能のうち、 どれが 4.2 ブランチにも採用されるのか、 その基準はどうなっているのかはわからないのですが、 「情報やメモ (10/06 2008)」, 「情報やメモ (10/16 2008)」 で紹介した CVS 版の -e オプションは 4.2.5 にも入ったようです。
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
MS-Windows Vista では wgnuplot (4.2.4) のヘルプファイルが見えず、 日本語版 .mnu ファイルによるメニューの日本語化もできない、 という質問がありました (556)。
Help の件は自力で解決したようですが、 「情報やメモ (02/13 2009)」 に書いた通り、WinHlp32.exe をインストールすれば利用できます。
メニューの日本語化ができない件は解決していないようですが、 私の手元には MS-Windows Vista がないので 残念ながら問題の確認や回避策を上げることができません。 もし何かご存じの方がいましたらご連絡ください (あるいは「gnuplot を使おう。その 2」に書いてあげてください)。
gnuplot の x11 terminal の出力の場合、グラフの線がスムーズではなく、 汚なすぎて見れないけど、 アンチエイリアスをかけたようなスムーズな出力にするには、 という質問がありました (569)。 set sample の話も出ていましたが、 wxt terminal でなんとか見れるようになった、 ということのようです (570,571,573)。
確かに wxt terminal のマニュアルを見ると、 wxt のグラフのレンダリングは色々やっているようなことが書いてあります:
描画のレンダリングは、ツールバーで対話的に変更できます。 出力をより良くするためにこのレンダリングは、アンチエイリアス、 オーバーサンプリング、ヒンティングの 3 つの機構を持っています。 アンチエイリアスは、水平や垂直でない線を滑らかに表示します。 オーバーサンプリングは、アンチエイリアスと組でピクセルよりも 小さいサイズでの精度を提供し、 gnuplot が非整数座標の直線を書けるようになります。 これは、対角方向の直線 (例えば 'plot x') が左右に揺れるのを避けます。 ヒンティングは、オーバーサンプリングによって引き起こされる水平、 垂直方向の線分のぼかしを避けます。 この出力形式は、これらの直線を整数座標に揃え、それにより、 1 ピクセル幅の直線は本当に 1 つ (1 つより多くも少なくもない) のピクセルで描画します。掲示板には、 「x11 terminal のグラフだと汚なすぎて見れなかったけど、 wxt terminal だと普通」とも書いてありましたが、 通常のグラフを書いている限りは、 個人的には両者の間にそれほどの違い (少なくとも汚なすぎて見れない、などという違い) は全く感じられません。
どのようなグラフを書いた場合、 あるいはどのような環境の場合 (例えば低解像度ディスプレイとか ?) にそうなるのか、 多少興味があるところです。
複数のグラフを書いた場合は、 グラフの色はデフォルトでは赤、緑、青の順になるけど、 それを「デフォルトで」青、赤、緑とするには、という質問がありました (574)。
この「デフォルトで」というのは、 plot のコマンドラインで色を指定するのではなく、 何も指定しなくても青、赤、緑となるようにしたい、ということでした。 これにはいくつかの方法がありますが、 terminal によっても対処法が違います。
578 の回答にある set style increment を使用する方法は gnuplot-4.2 から導入されたもので、 カラーが使える terminal では一般的な方法です。 wxt terminal ではこれを用いないとデフォルトの色の並びは変更できません。
(cf. 「情報やメモ (08/21 2009)」)
前回の報告 (11/02 2008)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回の報告も、4 ヶ月も空いてしまったため、 かなり多くの改良等が行われています。 既にいくつか報告したものも含まれていますが、 今回の大きな変更、追加等は以下のものでしょうか。
canvas terminal は、HTML 5 の canvas 要素を利用した terminal のようで、 javascript コードを含む HTML 出力を行います。 確認したところ、 Solaris 9 上の Firefox-2.0.0.20 や Netscape-7.0、 MS-Windows XP 上の MS-IE 7 では表示できませんでしたが、 Solaris 9 上の Opera-9.64 や MS-Windows XP 上の Firefox-3.0.6 では表示できました。
Lua terminal は、最近話題のスクリプト言語 Lua に対応したもののようで、 今のところ、最終的に pdflatex にかけるための出力を吐くものようのです。 ただ、Lua についてまるで知りませんので、 どうするものかまるでわかりませんし、何が必要なのかもわかりません。
なお、上の「その他」に書いた「man/gnuplot-ja.1」は、 Unix 用のオンラインマニュアル man/gnuplot.1 (Unix 用なのでほぼ x11 terminal 用のマニュアル) を日本語訳したもので、 今回採用されました。 次版のマニュアル日本語訳の配布からこれも追加する予定です。
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
目盛りの表記を
100という風に 100 倍にしたい、という質問がありました (529)。
1
0.01
1e-04
1e-06
「log じゃだめなの」という簡単な答しかついていませんでしたが、 これはもちろん対数軸にすればいいだけです。 質問の書き方から、多分 y 軸を対数軸にしたいようなので、
set yrange [1e-06:100]とすればいいでしょう。 なお、先頭のものがないと デフォルトの範囲は 0.01≦y≦1 になってしまいますし、 2 番目のものがないとデフォルトの目盛り間隔は 10 倍になります。 また、「1e-04」は Linux 以外では多分「0.0001」となるはずなので (cf. 「情報やメモ (03/31 2007)」)、 必要ならば
set ytics 100
set logscale y
set ytics (1e-06, "1e-04" 1e-04, 1e-02, 1, 100)のような明示的な指定を行う必要があります (1e-04 だけ明示的に書けばよい)。
皆で plus patch を 4 系に移植しないか、という提案がありました (532)。
plus patch とは以前山賀正人さんが配布していたもので、 gnuplot への追加機能として postscript terminal で LaTeX のような書き方による文字列の記述が可能になるもので、 実際には日本語化やヒストリ機能の拡張なども含まれていました。
掲示板にはあまりいい返事はなかったようですが、 実は 「情報やメモ (05/20 2008)」 で紹介したように、 Vine Linux の gnuplot-4.0 には plus patch の移植されています。 4.2 以降の移植の可能性についてもそちらを参照してください。
gnuplot でデータの最大値、最小値、平均値を表示させたいのですが、 という質問がありました (543)。
gnuplot だけでやるのは無理、という答えがついていましたが、 確かに平均値を知るのは無理ですが、 最大値と最小値ならば、gnuplot-4.2.4 であれば知ることができます。
gnuplot-4.2 以降から読み出し専用の内部変数 GPVAL_* というものが サポートされていますが (show variable all で一覧を参照可能)、 その中に GPVAL_DATA_Y_MIN, GPVAL_DATA_Y_MAX というものがあります (GPVAL_DATA_*_{MIN,MAX} は gnuplot-4.2.4 以降)。 それらの変数には直前に描画したグラフのその軸のデータの最小値、 最大値が保存され、それを読み出すことができます。 なお、関数描画も実際には標本したデータを関数から生成しているので、 関数描画に対しても指定した範囲での最小値、最大値 (の近似値) が それらの変数にセットされます。
よって、例えば最小値、最大値に線を引くには、以下のようにすればできます (gnuplot-4.2.4 以降のみ)。
set yrange [-2:2]';' より前の一回目の plot は GPVAL_DATA_Y_{MIN,MAX} に 値を入れさせるための空出力で、 それにより GPVAL_DATA_Y_{MIN,MAX} がセットされます。 よって、その次の replot 以降が実際に欲しい出力ですが、 これは画面出力 (set term x11 等) の場合で、 画面出力でない場合は、最初の plot を一時ファイルへの出力とでもして、 2 回目の replot を正式なファイルへの出力とすればいいでしょう。 なお、replot の後ろの引数は、直前の plot 命令に ',' をつけて その後ろにそのままつなげられるので、replot の直後には ',' は不要です。
plot sin(x) ; \
replot GPVAL_DATA_Y_MIN title "min", GPVAL_DATA_Y_MAX title "max"
なお、この例の sin(x) に対する GPVAL_DATA_Y_MIN の値は 理論上の最小値である -1.0 に丁度等しいわけではなく、 実際の値は -0.999384557612436 となっています。 これは、あくまで関数描画を標本した点での値の最小値を保持しているからで、 その標本点が丁度最小値を与える x でなければ 理論上の最小値とは一致しないからです (上で近似値と書いたのはそういう理由です)。
ところで、GPVAL_* の内部変数は次々追加され、 「show variable all」では例えば最新の開発版の gnuplot-4.3 では 一画面におさまらない位の大量のものが表示されてしまうのですが、 その gnuplot-4.3 では show variable も改良され、 「show variable GPVAL_」「show variable GPVAL_DATA_Y」のように それで始まる変数名の変数の一覧だけを見ることができるようになっています。 gnuplot-4.2.4 等にはフィードバックされていませんが、 バグや問題を調べたりする際には実はそれなり便利な機能です。
ちなみに、GPVAL_DATA_Y_MIN 以外に GPVAL_Y_MIN というものもありますが (gnuplot-4.2.0 以降)、 これは直前の描画の「yrange」の最小値を指します (上の例で言えば -2.0)。
不連続な関数 (実際は 8*x-floor(8*x)) をプロットすると 直線で不連続部分も結ばれてしまうのですが、 という質問がありました (551)。
関数描画では基本的に標本化したデータを with lines で表示しますので、 不連続な箇所は急峻にはなりますが確かに直線で結ばれてしまいます。 回答としては、set sample で標本数をかなり増やして with dots で描画する、 という例が上げられていました。 with dots なら線では結びませんのでこれでいけますが、 回答例には set sample は 10 万としてありましたが、 多分どんな高解像度のディスプレイであっても 10 万までは必要なく、 せいぜい 1 万位で十分だろうと思います。
これの別解として、with lines でも 不連続点を結ばないようにする方法を紹介します。 簡単のために、対象とする不連続関数を
f(x) = x-floor(x) (すべての整数 x で不連続)とします。
gnuplot の with lines は「未定義値」がある場合には、 そこを線では結ばない、ということになっていますので、 その不連続点の y の値を未定義値にしてしまえばいいわけです。 ただし、丁度その不連続点だけを未定義値とするために、
f(x)=x-floor(x)としてもうまくいきません (NaN は gnuplot-4.2 以降で定義されている未定義値、 gnuplot-4.0 以前の場合は 1/0 を代わりに使用する)。 それは、関数描画は「標本化された点のデータに対する折れ線描画」だからで、 丁度標本点がその不連続点に当たるとは限らないからです。 よって未定義値を与える不連続点の周囲に多少幅を持たせて、 その範囲では関数値は未定義、のようにする必要があります。 例えば以下の通りです。
g(x)=(x==int(x))? NaN : f(x)
plot g(x) title "f(x)" with lines
EPS = 0.01h(x) は |x| の小数部分ですから、 それが 1-EPS より大きい場合、 および EPS より小さい場合は g(x)=NaN で、 それ以外は g(x)=f(x) としています。 すなわち任意の整数 n に対して「n-EPS<x<n+EPS」 の場合に未定義となるようにしたのが g(x) ということになっています。 これを、標本間隔が 2*EPS = 0.02 より小さくなるようにして (set sample で適当に大きい値をセットして) 描画すれば、 確実に各不連続点の近くの 1 つの標本点が未定義値となりますから、 線が不連続付近で切れて描画されることになります。
f(x)=x-floor(x)
h(x)=abs(x-int(x))
# h(x) は |x| の小数部分
g(x)=(h(x)>1-EPS)? NaN : (h(x)<EPS)? NaN : f(x)
plot g(x) title "f(x)" with lines
なお、上の例では h(x) を |x| の小数部分として abs(x-int(x)) を使いましたが、 実はこの例の f(x) 自体が「x の小数部分」となっているので、 h(x) などを使わなくても
g(x)=(f(x)>1-EPS)? NaN : (f(x)<EPS)? NaN : f(x)としても同じ効果が得られます。 また、abs(x-int(x)) は「|x| の小数部分」ではなく、 「|x の小数部分|」ではないか、と思われるかもしれませんが、 「負の値の小数部分」には、次のような 2 つの立場があると思います。
数学屋は通常前者を取りますが、 そこに誤解がないように「|x|の小数部分」と書いています。
それでも、x が負の場合には「|x| の小数部分」と 「|x の小数部分|」とは違うのでは、h(x) は本当に |x| の小数部分か、 と思われるかもしれませんので、少し説明しましょう。 以下、整数部分、小数部分という言葉は前者の立場で考えます。
実は gnuplot の int(x) は、 x が正の場合には x の整数部分 (= floor(x)) なのですが、 x が負の場合には x の整数部分 (= floor(x)) ではなく、 「-(|x| の整数部分)」(= ceil(x)) となっています。
floor(x) ceil(x) int(x) x が整数 x x x x=2.2 2 3 2 x=-2.2 -3 -2 -2
よって、x-int(x) は x=-2.2 に対しては -0.2 となりますので、 この x-int(x) は後者の立場での小数部分を意味することになります。 ゆえに abs(x-int(x)) は「|x| の小数部分」となるわけです。 int() という関数自体が floor(), ceil() の 中間の性質を持つようなものとして導入されているわけですが、 逆にそれが前者の立場 (数学者の立場) の整数部分 (= floor(x)) とはずれがあり、少し厄介です。
ちなみに、掲示板には floor() なんて関数が実装されているのか、 という感想もその後で寄せられていますが、 実は floor() は gnuplot-3.5 には既に存在しています。 利用できる関数は help functions で知ることができますが、 gnuplot-3.7.2 では 49 個、gnuplot-4.2.4 では 66 個が表示されます。 基本的な数学関数やベッセル関数などの特殊関数、 正規分布などの統計関数、乱数などの他に、 gnuplot-4.2 以降では文字列処理関数なども実装されてきていますし、 開発版の gnuplot-4.3 では楕円積分の値 (3 種類の完全楕円積分の値) も利用できるようになっています。
(cf. 「情報やメモ (04/02 2009)」)
先日、研究室のコンピュータのログを 以下のような「日付 データ」の形式で取りました
01/25 363ここでふと、これを gnuplot でグラフにして、 x 軸の見出しにこの 1 列目の日付を表示させるには、と考えたのですが、 これは gnuplot-4.2 以降にある xticlabels(n) (xtic(n) と略記可能) という機能を使えば可能です。 仕様は help datastrings, help using xticlabels で参照できますが、 これはある列を文字列として軸の見出しに使用する指定で、 using 指定内で使用します。
01/26 313
...
しかし上のようなデータの場合、 日付を数値に変換しない限りは x 座標のデータが自体がないので、 描画する際は、以下のいずれかを選択することになります。
本来は最初の方が真っ当ですが、2 番目の方が楽なのでそちらでやってみました。 ところがここに問題がありました。 単純に以下のようにすると、すべての行の目盛りがつけられてしまいます。
plot 'data' using 0:2:xtic(1) with lp
通常は以下のように「set xtics 5」のようにすれば ちゃんと目盛りが 5 つずつおきになるのですが、 なぜか xtic(1) がついている場合はうまくいかず、 「set xtics 5」「set xtics 0,5,44」などとしても変化ありません。
set xtics 5
plot 'data' using 0:2 with lp
もしかしたらこれはバグなのかもしれませんが、 これをとりあえず回避するにはどうしたらいいか考えてみました。 単純に考えられるのは、2 回描画命令を出して、 1 回目で目盛りの出力、 2 回目でグラフの出力を行う、というよくある手です。 1 回目は every を使えばいくつかおきの出力が可能ですから、 それで軸の目盛りを間引くことができそうです。 ところが、そう思って以下のものをやってみると、これがまたうまくいきません (グラフが見やすいように、1 回目と 2 回目の出力の色を変えています)。
plot 'data' every 5 using 0:2:xtic(1) with p,\
'' using 0:2 with lp lt 3
グラフを見てわかるように、なぜか 1 回目の出力が左に寄ってしまいます。 どういうことかと show variable GPVAL_X (gnuplot-4.3 の機能) や、 xtic(1) を取って出力させることでわかったのですが、 どうやら「every 5 using 0:2」の場合は、 x の座標値は、5 つおき (0,5,10,15,...) ではなく 1 つおき (0,1,2,3,...) になってしまうようなのです。 つまり every を使用した場合は、0 列目の値は元のデータの行番号ではなく 「every で間引いた後の行番号」だということになります。
なんとなくこれもバグのような気がしますが、 これを回避するには単純にそのデータ番号を 5 倍してやればいいので、 以下のようにすればいいことになります。
plot 'data' every 5 using ($0*5):2:xtic(1) with p,\
'' using 0:2 with lp lt 3
なお、1 回目のグラフの表示や key が邪魔ならば、 lt -2 や notitle を使って以下のようにすれば OK です。
plot 'data' every 5 using ($0*5):2:xtic(1) with p lt -2 notitle,\
'' using 0:2 with lp lt 3
上記の 2 つの問題点、すなわち、
については、時間のあるときに調べてみたいと思います。
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
5000 点位のデータで描画にかなり時間がかかるのですが、 描画の途中経過が分かるようにできないでしょうか、という質問がありました。
多分、win, aqua, x11, wxt 等の対話型出力形式での話だろうと思います。 確かにそういうこともできそうな気がすると思いますが、 残念ながら gnuplot では難しいと思います。 gnuplot は、画像出力も画面出力もプリンタ出力も、 基本的に同じ原理で出力しているのがその理由です。 例えば、データを分割して表示させるために、
をした後で、
をさせようとすると、(2) のときには (1) のデータのグラフは消えて、 (2) だけが表示されます。 よって、(1) を書いた後で (1) と (2) をともに表示させるには、 (1) の次に
をさせる必要がありますが、 この (3) はもちろん 200 行分の時間がかかってしまうので、 途中経過のようなものを見せるような目的では意味がなくなります。
(1),(2) の重ね書きを (3) 以外にやる手段として、 multiplot がありますが、 これも徐々に表示させるような目的では使えないのではないかと思います。
set object (gnuplot-4.3) だと、 前の描画を残したまま描画 (object) を追加できますが、 これは逆にデータから各 object の座標を取り出すのが難しいので やはり使えません。
となると、gnuplot (X11 環境ならむしろ gnuplot_x11) を改造して、 今どこまで点を読み込んでいるところかの途中経過を stderr に表示させる、といった方法がある程度でしょうか。 gnuplot_x11 のそういう改造ならば、それほど難しくないかもしれません。
なお、その後松田@東京電機大さんが指摘したように、 現在のコンピュータならば 5000 点位の描画で それほど時間がかかることはあまり考えられません。 特殊な目的でよほど非力なコンピュータを使っているか、 何か別な問題が起きている可能性があります。
(1979 の記事から始まるスレッド 「プロットの途中経過」)
gnuplot-4.2 で 'set terminal png medium monochrome' としても 生成される画像が白黒にならない、という質問がありました。 実際そのように指定するとエラーになるそうです。
適当にインターネットなどを検索すると、 確かにそういう情報が得られるかもしれませんが、 gnuplot-4.2 ではそれは正しくありません。
実は、png terminal には、以下の 2 つがあります (現在の gnuplot-4.3 の libcairo を使用する pngcairo terminal も入れれば 3 種類)。
古い png terminal には確かに monochrome オプションがありましたが、 現在の png terminal にはそれはありませんので使えません。 インターネットの情報よりまずは gnuplot の help をあてにしてください。 そして、その gnuplot の help の png terminal の項をちゃんと見ていれば、 モノクロのための設定例が書いてあることにも気がついたはずです。
なお、松岡さんからも指摘があったように、 むしろ postscript terminal などで eps 画像出力を作っておいて、 それを png 画像に変換した方が綺麗なものができるかもしれません。
(1980 の記事から始まるスレッド 「png のモノクロ出力」)
MS-Windows Vista では .hlp 形式のヘルプはサポートされていないので、 gnuplot の標準のヘルプファイルが参照できないが、 Microsoft のサイトでダウンロードできる WinHlp32.exe をインストールすれば利用できる、という報告が 松岡さんからありました。 gnuplot の日本語マニュアルのページにも QandA に追加しておきました。
ほかにも、PDF ファイルで代用するとか、 HTML 形式に変換したものを Microsoft HTML Help Workshop で、 MS-Windows Vista が参照できる HTML Help 形式 (.chm) に変換する、 という手もあるようですが、いずれも今のままではややイマイチなようで、 松岡さんは後者をちゃんとしたい、と言っておられます。 期待したいところです。
(1996 の記事から始まるスレッド 「Windows Vista 上での windows 版での help ファイルの表示について」)
(cf. 「情報やメモ (03/30 2009)」)
gnuplot Q&A 掲示板 に以下のような質問がありました。
同心円状のデータがあるが、それを set pm3d map すると MxN のデータなのに (M-1)x(N-1) のピクセルしか構成されない。 MxN のピクセルを構成するにはどうしたらいいか。 (1987 の記事 「2次元マッピングでのアルゴリズム」) )その記事では with image についても触れていますが、 これを set pm3d map で考えてみましょう。
確かに set pm3d は「面」ベースの描画ではなく、 「頂点」ベースの描画となっていて、例えば
x11 y11 z11というデータがあったときに、(x11,y11) に z11 の値を書くのではなく、 (x11,y11),(x12,y12),(x21,y21),(x22,y22) という 4 点で作られる四辺形に z11,z12,z21,z22 の値の平均値に対応する色を塗ります。 例えば以下を試してみるとわかります:
x12 y12 z12
x21 y21 z21
x22 y22 z22
set pm3d map
splot '-'
0 0 1
1 2 2
2 1 6
3 4 7
e
このとき、(0,0), (1,2), (2,1), (3,4) を頂点とする四辺形が、
1,2,6,7 の平均値 4 で塗られます。塗る色を頂点での値に変えるには、
「set pm3d corners2color {c1|c2|c3|c4}」を使います。
上の例で試してみると、c1 は 6 ((2,1) での値、c2 は 7 ((3,4) での値、
c3 は 1 ((0,0) での値)、c4 は 2 ((1,2) での値) の値が
それぞれ使用されるようです:
よって、データを「面」ベースに set pm3d で描画したい場合は、 以下のように考える必要があります。
例えば、上のような 4 点 (xij,yij) (i=1,2, j=1,2) での描画を 「面」ベース、すなわち各 4 点に zij の色を塗りたい場合は、
p11 q11 z11のように 9 点のデータを与え、 (pij,qij), (pi(j+1),qi(j+1)), (p(i+1)j,q(i+1)j), (p(i+1)(j+1),q(i+1)(j+1)) の中心がほぼ (xij,yij) となるようにし、 その上で「set pm3d map corners2color c3」とすればいいわけです (z の値が 0 の点は、頂点を作るためだけのダミーデータ)。
p12 q12 z12
p13 q13 0
p21 q21 z21
p22 q22 z22
p23 q23 0
p31 q31 0
p32 q32 0
p33 q33 0
これを同心円データでやった例を以下に示します。 最初のグラフは、以下のようなデータに対して set pm3d のみで描画したものです:
1*cos(0*π/4) 1*sin(0*π/4) 1
1*cos(1*π/4) 1*sin(1*π/4) 2
1*cos(2*π/4) 1*sin(2*π/4) 3
...
1*cos(7*π/4) 1*sin(7*π/4) 8
2*cos(0*π/4) 2*sin(0*π/4) 9
2*cos(1*π/4) 2*sin(1*π/4) 10
2*cos(2*π/4) 2*sin(2*π/4) 11
...
2*cos(7*π/4) 2*sin(7*π/4) 16
見てわかる通り、四辺形は 7 つのみで、 その位置は各データ点の座標を頂点とするもので、 面の色も平均化されたものとなっています。
次のグラフは、この描画を面ベースにするために、 座標データをずらしてダミーの点を追加したものに対して、 set pm3d map corners2color c3 としたものです。
0.5*cos(-0.5*π/4) 0.5*sin(-0.5*π/4) 1
0.5*cos(0.5*π/4) 0.5*sin(0.5*π/4) 2
0.5*cos(1.5*π/4) 0.5*sin(1.5*π/4) 3
...
0.5*cos(6.5*π/4) 0.5*sin(6.5*π/4) 8
0.5*cos(7.5*π/4) 0.5*sin(7.5*π/4) 0
1.5*cos(-0.5*π/4) 1.5*sin(-0.5*π/4) 9
1.5*cos(0.5*π/4) 1.5*sin(0.5*π/4) 10
1.5*cos(1.5*π/4) 1.5*sin(1.5*π/4) 11
...
1.5*cos(6.5*π/4) 1.5*sin(6.5*π/4) 16
1.5*cos(7.5*π/4) 1.5*sin(7.5*π/4) 0
2.5*cos(-0.5*π/4) 2.5*sin(-0.5*π/4) 0
2.5*cos(0.5*π/4) 2.5*sin(0.5*π/4) 0
2.5*cos(1.5*π/4) 2.5*sin(1.5*π/4) 0
...
2.5*cos(6.5*π/4) 2.5*sin(6.5*π/4) 0
2.5*cos(7.5*π/4) 2.5*sin(7.5*π/4) 0
これは、各描画単位の中心と色がほぼ元のデータの各点に対応しています。
これを元のデータと gnuplot だけでやるのは難しいでしょうから、 最終的に gnuplot で描画することを考えてデータを出力する、 あるいは出力したデータを加工する、 というのがいいのではないかと思います。
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
松岡@名古屋大 さんから、いくつか MS-Windows 版のコンソールモードの gnuplot に関する情報が投稿されました。
今まで、MS-Windows 用の gnuplot の配布物には、 以下の 1., 2., 3. の実行バイナリのみが含まれていましたが、 CVS 版では、それに加えて 4. の実行バイナリの形態が追加されました。
コンソールモードの gnuplot とは、 GUI のウィンドウの上でコマンドを実行させる代わりに コマンドプロンプト上でコマンドを入力するようなものです。 その点では wgnuplot.exe より「劣っている」と言えなくもないですが、 プログラムなどから wgnuplot.exe を呼び出す場合に、 従来は pgnuplot.exe を経由して呼びださなければいけなかったものが、 単に gnuplot.exe を呼びだすことで行えるようになったことがメリットのようです。 つまり、「gnuplot.exe = wgnuplot.exe + pgnuplot.exe - GUI」 といった感じですが、wgnuplot_pipes.exe でしか使えなかった "< command" のような入力も、コンソールモードの gnuplot.exe はできるようです。 MS-Windows 上で、Octave のように他のプログラムから gnuplot を使う場合を 意識したもののようです。
現在配布されている以下の MS-Windows 版のコンパイル済みバイナリには、 いずれも上記 4 種類の実行バイナリが含まれています。
なお、角藤さん公開版には、最近追加された Lua terminal 用に、 Lua インタープリタ/コンパイラの lua.exe, luac.exe もついているようです。
松岡@名古屋大 さんから、Cygwin 環境で PostScript 出力を fig2dev で EMF に変換した場合の情報が提供されました。 その記事にリンクが貼ってある松岡さんの WWW ページに詳しい話が書いてあります。
(1952 の記事 「gnuplot の postscript (ps) 出力の windows ソフトへのとりこみ(再) (要 cygwin)」
「x 軸と y 軸の数値の比」を指定したいのですが、という質問がありました。 グラフの大きさを変えても比は一定になるようにできませんか、という話でした。
x 軸と y 軸の「比」には、例えば以下のようにいくつかの意味が考えられます。
1. は、例えばグラフ全体の横幅が 5cm で縦幅が 2cm なので比は 2/5=0.4、 といったことを意味し、 2. は、例えば x 軸の範囲が -10 から 10 までの 20 で y 軸の範囲が -1 から 1 までの 2 なので比は 2/20=0.1、 3. は、例えば x 軸の 1 は 5cm/20 = 0.25cm で y 軸の 1 は 2cm/2 = 1.0cm なのでその比は 1.0/0.25=4.0、 ということを意味します。 なお、この例から容易にわかるように、 (3. の比)=(1. の比)÷(2. の比) となります。
1. の比、つまりグラフのアスペクト比は set size ratio で設定します。 2. の比は、set xrange と set yrange で設定します。 よって、3. の比は 1. と 2. を組み合わせてもできるのですが、 gnuplot では、set size ratio に負の値を設定すると 3. の比が設定できるようになっています。
元記事の人はどうやら 3. の比を指定したいようでしたが、 グラフの大きさをマウスなどで変えても比を固定したい、 という要望のようでした。 しかし、グラフをマウスで x-方向/y-方向に拡大/縮小したりすると、 一旦それに合わせて x-方向/y-方向が拡大/縮小された表示になります。 その後で replot を実行すれば、新しい大きさのウィンドウの中で 正しくその比の通りに表示し直されます。 なお、その場合は xrange と yrange の値 (上の 2.) は変わらずに 必要ならばウィンドウ内に余白を作って set size ratio の値になるように 描画し直されます。
本当は、set size ratio が設定されている場合は、 マウスでの拡大/縮小に合わせて描画が書き直されるときに replot を発行したのと同じことまでやればいいのかもしれません。 そちらの方がいいのだとすれば、 つまり replot を発行しない中途半端な状態のグラフにメリットがないとすれば、 そういう風に改良するのもいいかもしれません。
(1953 の記事から始まるスレッド 「軸の比」)
A4 用紙に正確に寸法を指定したいのですが、という質問がありました。 postscript terminal で、紙の左上からの位置を正確に指定したいのだけど うまくいかない、ということでした。
グラフのサイズについては、gnuplot-4.2 以降では ほぼ以下のように統一されてきています。
つまり、印刷する紙の大きさは term オプションの size 指定で行いますが、 その中のグラフの大きさや位置は set size と set origin で行います。 なお、set size や set origin は絶対的な数値での指定ではなく、 相対的な値 (拡大率) 指定になっています。
gnuplot のグラフは、グラフの軸の四角い枠 (取り敢えず「軸枠」と呼びます) の外に軸の目盛りの数字やタイトルなどが表示されます。 gnuplot の set size や set origin の設定は、軸枠の外のこれらの文字 (および set margin による余白) を含んだ「描画領域」に対して行われますので、 これらの文字のサイズなどが変わると軸枠の位置もずれます。 よって軸枠の位置を指定したい場合は、 どうしても set size や set origin を微妙に調整する必要があります。
その場合、相対指定だと調整が面倒、という意見もありましたが 簡単な数式を指定することもできますから、
set term post landscape color size 29.7cm, 21.0cmのように書けば済むと思います。
set out 'a4.ps'
set size 15.0/29.7, 15.0/21.0
set origin 1.0/29.7, (21.0-15.0-1.0)/21.0
set out
なお、gnuplot-4.2 以降の場合は、 set margin を使って「軸枠の位置」を調整できるようになっています (元々は multiplot 用) ので、 これを利用すれば周りの文字によらない設定が可能です。
(1970 の記事から始まるスレッド 「A4 用紙に正確に印刷するには」)
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
eps 出力 (set term post eps) で、set size square としたときに、 出力される EPS ファイルの右に余白ができてしまう、という質問がありました (520)。
確かに gnuplot-3.7, gnuplot-4.0 では EPS ファイルの BoundingBox は横長になっていて (5 x 3.5 inch)、 グラフは左に寄って右側に余白ができますが、 gnuplot-4.2 以降では、デフォルトではやはり同じ横長サイズなのですが、 グラフはセンタリングされて左と右に同じ位の余白ができます。
gnuplot-4.0 以前でその余白を削除するには、 「情報やメモ (01/22 2006)」 に紹介した ghostscript (を利用したスクリプト) や ps2eps を利用する方法があります。
gnuplot-4.2 以降の場合は、その方法に加えて terminal オプションで 出力ファイルサイズを指定する、という方法があります。 EPS の場合はデフォルトの出力は 5 x 3.5 inch ですから、
set term post eps size 3.5,3.5とすれば余白のない正方形の EPS 画像が作られます (gnuplot-4.0 以前は不可)。
set size square
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
最新版に近い本ってありますか、という質問がありました (472)。 なお、4.2 か 4.3 用の gnuplot 本をそろそろ出して欲しい、 という話も以前ありました (418)。
現在の最新リリース版である gnuplot-4.2 がリリースされたのは 2007 年 3 月で、 その後にはまだ gnuplot の本は新規には出版されてはいないようですから、 最新版に最も近い本は、gnuplot-4.0 に対する本だろうと思います。
gnuplot のページの 「文献等」 に書いてある本で言えば、対応バージョンは以下のようになっているようです (「書名」(出版時期): 対応 gnuplot version)。
「GIMP...」だけ手元にないのではっきりしませんが、 これは出版時期からして、gnuplot-3.7.1 以前のものだろうと思います。 よって、この中では最も新しい版に対応しているのは、 「使いこなす gnuplot 改訂第 2 版」だということになります。 ただしこの本は、 元々 gnuplot-3.5 用に書かれた「使いこなす gnuplot」から それほど内容は変わっておらず、 よってそれほど gnuplot-4.0 用のことが書いてあるわけではなく、 むしろ最初から gnuplot-3.7 用に書かれた 「gnuplot パーフェクト・マニュアル」の方が 新しい内容が含まれているくらいなので、 選択はやや難しいところかもしれません。
ちなみに、gnuplot の各リリース版のリリース日は、 version.c やドキュメント等から見ると以下のようになっています。
バージョン | 公開日 | バージョン | 公開日 |
---|---|---|---|
1.1.0A | 1989-05-18 | 4.0.0 | 2004-04-15 |
2.0 | 1990-03-07 | 4.2.0 | 2007-03-03 |
3.2 | 1992-03-24 | 4.2.1 | 2007-08-27 |
3.5 | 1993-08-27 | 4.2.2 | 2007-08-31 |
3.7.0 | 1999-01-14 | 4.2.3 | 2008-03-08 |
3.7.0.1 | 1999-08-11 | 4.2.4 | 2008-09-22 |
3.7.1 | 1999-10-22 | ||
3.7.2 | 2002-01-25 | ||
3.7.3 | 2002-12-12 |
3 次元描画で、x 方向と y 方向の幅を変えたい、という話がありました (473)。
視方向 (set view) や set size を変えれば、 それなりに縦と横のサイズを変えることはできるのですが、 基本的には splot グラフの底面 (x,y 方向) の「見た目」の形は 正方形固定のようです。
無理矢理、したければ、例えばデータが x 方向に 0 から 100 まで、 y 方向には 0 から 20 までしかない場合に、
set xrange [0:100]のようにすれば、y 方向は狭い範囲だけグラフが書かれることになります。 底面の制御は難しいですが、例えば multiplot を使えば、 底面にその範囲を示す線位は書くことはできるでしょう。
set yrange [0:100]
set multiplotset border で不要な線を多少消して、 必要な線をさらに別な関数のグラフの等高線として書くことで 底面を構成するということもできますが、 面倒なだけですね。
set xrange [0:100]
set yrange [0:100]
set zrange [-100:100]
unset surface
unset key
set contour
set cntrparam levels discrete 0
splot y-20 # 等高線として y=20 の線を底面に書く
set surface
set key
set zrange [*:*]
set ztics
splot 'data' w l
splot で Z 軸を (x,y)=(0,0) に立てたい、という質問がありました (476)。
これは、例えば set arrow で書くことはできます。
set arrow from 0,0,-2 to 0,0,2 head lw 1.2 lt -1ただし、このままでは目盛りはつきません。 目盛りもつけたければ、gnuplot-4.3 なら set for を使って 例えば以下のようにできます:
i1 =-5
i2 = 5
pos(i)=i/5.0
str(i)=sprintf("%g",i/5.0)
ticlen=0.5
set arrow from 0,0,-2 to 0,0,2 head lw 1.2 lt -1
set for [i=i1:i2] arrow from 0,0,pos(i) rto ticlen,0,0 nohead lw 1.2 lt -1
set for [i=i1:i2] label str(i) at first -0.5,-0.5,pos(i) right
splot sin(x+y)
2 次元で非常に長いグラフを作成してマウスでグラフをスクロールできないか、 という質問がありました (481)。
gnuplot では確かにそのようなことはできず、 ウィンドウサイズに丁度全部が収まる形でグラフは表示されます。
しかし例えば Unix であれば、gif/png などの画像出力にすれば、 その画像を xli や display などで一部画面表示で見れば、 マウスでグラフをスクロールして見ることになります。
スクリプトを使って、あるいは emacs の gnuplot-mode で グラフを作成しているのであれば、 gif/png などの画像出力にすることは、 対話型の画面出力とそれほど違いなくできます (むしろエディタの編集機能が使える分効率的)。
x11 terminal (enhanced) で title 文字列で "a_b" と書くと b が下添字になってしまうが、そうしないようにするには、 という話がありました (483)。
"a\_b" だとうまくいかない、ということでしたが、 484 で回答があったように二重引用符内では 正しくは "a\\_b" としなければいけません。 または、単一引用符内ならば 'a\_b' とします (詳しくは help quote 参照)。
なお、文字サイズが通常の半分位になってしまう、 という話もあったのですが、それはこちらでは再現できませんでした。
terminal が一杯あるんだけど、昔は端末って沢山あったんですか、 という質問がありました (494)。
gnuplot は「出力形式」を terminal と呼んでいますが、 実際にはそれには「スクリーン端末」や「プリンタ」が含まれていて、 さらに画像ファイル形式の出力などもありますから、 実際に「端末」と呼べるものばかりではありません。 よってうちの研究室で作成している日本語マニュアルでも、 "terminal" は「端末」ではなく「出力形式」と訳しています。
そして、特に画像形式などが新たに追加されていますので、 むしろ terminal の種類は徐々に増えています (中には削除された terminal もあります)。
実際にいくつの terminal をサポートしているのかは、 ちょっと数えるのが面倒なんですが、 例えば最新のリリース版である gnuplot-4.2.4 では、 だいたい 100 個位の terminal をサポートしています。 ざっと分類すると以下の通りです (漏れがあるかも):
aed767, aed512, amiga, apollo, aqua, atari, vdi, be, cgi, svga, dumb, emxvga, emxvesa, vgal, hercules, egalib, egamono, vgalib, vgamono, svgalib, ssvgalib, ggi, gpr, grass, iris4d, linux, macintosh, mgr, mif, mtos, next, openstep, dospc, pm, sun, unixpc, vgagl, VWS, windows, wxt, x11, xlib
hcgi, dxy800a, epson-180dpi, epson-60dpi, epson-lx800, nec-cp6, okidata, starc, tandy-60dpi, excl, hp2623a, hp2648, hp500c, hpgl, pcl5, hpljii, hpdj, hppj, imagen, kyo, prescribe, qms, tek410x, tek40xx, vttek, kc-tek40xx, km-tek40xx, selanar, bitgraph, vx384
aifm, cgm, corel, dxf, eepic, emf, fig, png, jpeg, gif, gnugraph, gpic, emtex, latex, mf, mpost, pbm, pdf, epslatex, pslatex, pstex, postscript, pstricks, regis, rgip, uniplex, svg, texdraw, tgif, tkcanvas, tpic, unixplot
debug
「スクリーン端末」には、確かに古いコンピュータ用の スクリーンドライバもそれなりに含まれていますが、 パソコン用のドライバが複数含まれているようです。 現在実際に使用/保守されているのは、多分
aqua (Mac OS X 用)、pm (OS/2 用)、windows (MS-Windows 用)、 wxt (wxWidgets グラフィックウィジェット環境用)、 x11 (Unix X Window System 用)くらいではないかと思います。
データファイルの先頭行の値を保持しておいて、 それをデータの各行から引いた値のグラフを書きたい、 という質問がありました (492)。
データを前処理しておいて、それを gnuplot に食わせる、 というのが正当な方法ですが、質問者は gnuplot 内でやるために ! を使って head, awk などを使ってその値を取得してみたのだけど、 それを gnuplot 内で利用する方法がわからない、と書いていました。
残念ながらまともな回答がついてないようですが、 gnuplot-4.2 以降なら sytem() 関数の返り値を使って、 システムコマンドの標準出力を gnuplot 内で利用できます:
d = system("awk '(NR==1){print $2; exit}' file")明示的に数値として取得したい場合は (デフォルトでは文字列値)、 help system に書かれているように system() に real() でもかぶせます。
plot "file" using 1:($2-d) w l
なお、パイプをサポートしている環境では、 awk などのコマンドの出力を gnuplot の入力とすることもできますから、
plot "< awk '(NR==1){d=$2}{print $1,$2-d}' file" w lのような手もあるでしょう。
極座標を使用している場合目盛りが負にならない、 という質問がありました (512)。 http://t16web.lanl.gov/Kawano/gnuplot/polar.html にはちゃんと負になっているのに、という話のようでした。
実は 「情報やメモ (07/30 2007; no.3)」 にも書いてありますが、 set polar の目盛りは、gnuplot 3.7 以降に挙動が変更されましたが、 上のサイトのサンプルは多分それ以前のサンプルです。 極座標では原点からの距離を考えますので、 現在の gnuplot では原点を 0 として、 どの方向にもそこから正の値が増えるように 目盛りが振られるようになっています。
よって現在の版では、逆に上のサイト (gnuplot-3.5) のような 目盛りを振るのは少し面倒ですが、無理矢理やるとすれば、 例えば以下のいずれかのような手があります。
ラベルをひとつずつ設定するのは面倒ですが、gnuplot-4.3 ならば set for を利用して以下のようにして明示的なラベルを振れます。
set polarmultiplot を使用するという方法は、例えば以下の通りです。
i1=-5
i2=5
pos(i)=i/2.0
str(i)=sprintf("%g",i/2.0)
set for [i=i1:i2] xtics ( str(i) pos(i) )
plot 1+sin(t)
set multiplot
set xrange [-2:2]
set yrange [-2:2]
unset key
plot 1/0
set key
set polar
plot 1+sin(t)
unset multiplot