ページが長いので「しおり」の仕組みを用意してみました。
「しおり用」と書かれた所をクリックしてからブックマークに入れると、
それはページの先頭ではなく、その箇所へのブックマークになります。
(03/03 2006)
今までちゃんと説明していませんでしたが、
ここには、日付ごとに記事 (記事 A とします) を書いていますが、
その最後に、(cf. 「情報やメモ (XX/XX 20XX)」)
のように別な日付の記事 (記事 B とします)
へのリンクがついているものがあります。
これは、「被参照リンク」で、
記事 B が記事 A を参照している (リンクを貼っている) ことを意味します。
つまり、記事 B の方が記事 A より後の記事であり、
記事 A の続きや追加情報、訂正などの内容であったり、
記事 A に関連する別な話題であったりしますので、
記事 A に被参照リンクがついている場合は、
是非そちら (記事 B) もご覧ください。
(01/29 2014)
前回の報告 (09/23 2016)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回は、wgnuplot 回りの修正もかなり入っていますが、 主要なものは以下のものでしょうか。
箱付き文字列の回転については、現在は出力形式依存ですが、 いくつかの出力形式で可能になっているようです。
ループのコードの刷新については、
例えば「for [i=1:N] for [j=i:i+1] f(i,j)
」のように、
ネストされている場合の内側のループ条件として
外側のループ変数の値を使うことができるようになったようです。
逆に言えば、今まではそれができなかった、ということでしょうが、
昔から gnuplot はループをちゃんと実装した言語ではなかったので、
その頃から考えればかなりまし、と考えて頂くしかありません。
(cf. 「情報やメモ (02/09 2017)」)
10/10 頃に、gnuplot-5.0.5 が公開されました。 5.0.5 での新規機能、変更、修正は以下のようです。
今回も変更、修正はそれほど多くはありませんが、 新規機能がいくつか追加されています。 いずれも既に CVS 版の新機能として以下で紹介したものですが、 CVS 版からそのいくつかが取り込まれたようです。 しかし、現在 CVS 版で可能となっている配列変数や 非線形軸、title, xlabel 等への boxed の拡張、 set view azimuth などの機能は 5.0 系ではまだ利用可能ではありません。 5.2 のリリースが待ちどおしいところでしょうか。
gnuplot の demo/ ディレクトリには現在かなりの数の demo が含まれていて、 all.dem をロードすればほぼすべての動作を追ってみることができます。 「情報やメモ (10/11 2011)」 にも書いたように、自動的にそれらを流すこともできますが、 今回それをファイルに落としてみました。 デモディレクトリで
gnuplot all.dem < /dev/null
とすれば all.dem が自動的に流れるのですが、例えば
gnuplot -e 'set term post color ; set out "all.ps"'
all.dem < /dev/null
とすれば、各画像を複数ページとして保存した PostScript ファイル all.ps
が作成されます。
ただし、いくつかのページは、gv で表示できない (エラーが出る) ようです。
他には引き続く plot 命令を複数ページとして保存するような出力形式は あまりありませんが、例えば、以下のようにして animated GIF ファイルを作ることができます。
gnuplot -e 'set term gif animate loop 1 ; set out "all.gif"'
all.dem < /dev/null
ただし、これは libgd 由来の gif terminal なので、
フォントが綺麗ではありませんし、うまく出力されないページもありそうです。
また、PDF 出力のために、
gnuplot -e 'set term pdfcairo color ; set out "all.pdf"'
all.dem < /dev/null
としてみたのですが、なぜか最後の demo 出力の後に Bus error を起こして、
出力された PDF ファイルが壊れていて開けませんでした。
一方、PNG 出力を
gnuplot -e 'set term pngcairo color ; set out "all.png"'
all.dem < /dev/null
とすると、相当大きな PNG ファイルができます。
本来 PNG ファイルは 1 ファイル 1 画像なんですが、
どうやら各 plot に対する PNG 画像出力が連結されたファイルが
出力されているようです。
PNG ヘッダを目印にすれば、
その PNG ファイルをそれぞれのファイルに分割することは
そう難しくはありません。
それに pngcairo terminal は libgd 由来の PNG
よりも綺麗な出力になりますので、
set term gif の animated GIF よりも
この PNG を GIF に変換して animated GIF を作る方がいいかもしれません。
せっかくなので、現在の CVS 版 (2016 10/05 辺りのもの; 5.1) で作った上の幾つかのデータ (pngcairo の出力を各画像に分割したもの、 gif terminal による animated GIF、 pngcairo の出力から作った animated GIF、 PostScript ファイル) を以下に置いておきます。画像数は 672 個あります。 なお、demo ディレクトリには all.dem に取り込まれていないデモファイルもいくつかあります。 それは以下のものには含まれていません。
(リンク等を修正しました。10/10 2016)
(cf. 「情報やメモ (09/05 2018)」)
前回の報告 (08/10 2016)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
なお、#[番号] と書いたのは、sourceforge に登録されている Bug tracker の番号で、それに対応した修正、 ということを意味します。 ChangeLog に書かれていたものを今回追加してみました。
今回の目玉は以下でしょうか。
今回は、新機能の追加がかなりありました。 上の 1., 4., 6., 8. 以外は特に説明はいらないと思いますが、 3. は colorbox の上下を入れ替えるもののようです。 今までは単純に軸を逆にするだけではうまく行っていなかった、 ということでしょうか。
1. は、従来の smooth frequency に対して、 合計が 1 になるような正規化を行います。 smooth frequency は、ちょっとした工夫でヒストグラムを書くことができますが、 それを smooth fnormal にするとそのヒストグラムの累積が 1 になるようにできる、 ということを意味します。以下にサンプルを紹介します。 データは、sin(x) の [0:pi] の範囲のデータを 1/1000 毎に出力した 1000 個のデータを使用しました。
set term wxt
set grid
bw = 0.1
set boxwidth bw*0.7
bin(x, w) = w*(floor(x/w) + 0.5)
set xrange [0:1]
set title "smooth frequency によるヒストグラム"
plot 'data' using (bin($1, bw)) with boxes smooth frequency not
pause -1
set title "smooth fnormal によるヒストグラム"
plot 'data' using (bin($1, bw)) with boxes smooth fnormal not
グラフも横軸も変わりませんが、縦軸のスケールが fnormal の方は 1/1000 になっていることがわかります。 それで総数が 1 になるわけです。
なお、このようなヒストグラムの場合は、fnormal を使わなくても 実は単純に、
plot 'data' using (bin($1, bw)):(0.001) with boxes smooth frequency not
とすれば同じことになります。2 列目を指定しなかった場合、
smooth frequency, smooth fnormal は 2 列目を 1 とみるので、
その高さ (y 座標) を 1/1000 倍すればいいわけです。
しかし、y の値が点毎に違うデータを全体の
y の合計に対する割合表示したい場合や、
点の総数がわからない場合などは単純にそのようにすることはできませんから、
smooth fnormal が役に立つのではないかと思います。
4. は、svg terminal の亜種 (svg ドライバの中に追加されたもの) として導入されたものです。 ただ、私には「DomTerm ターミナルエミュレータ」 なるものがわかりませんので、うまく説明はできません。 「DomTerm ターミナルエミュレータ」については、以下をご覧ください。
6. は、3 次元グラフで、z 軸の向きを回転する (傾ける) ものです。 splot では、従来は set view で視方向は変更できましたが、 z 軸は常に鉛直方向を向いていました。 それが「set view azimuth」により傾けられるようになりました。 これについては、すでに本家のサイトにサンプルがありますので、 そちらをご覧ください。
なお、マウスで z 軸を回転する場合は、 右ボタンクリック/ドラッグを使用するようです。
8. は、配列の要素数を表す演算子の導入です。
絶対値 (または行列式) のような記法ですが、
|A| で配列 A の要素数を意味します。
例えば、配列の要素数がはっきりとはわからない場合でも
「plot for [i = 1 : |A|] f(A[i])」
」
のような書き方ができるようになります。
データ点を配列に保存する場合など、
色々と便利に使えるかもしれません。
(cf. 「情報やメモ (10/31 2016)」)
「情報やメモ (08/19 2016)」
に書いた、「GPVAL_ でホスト名もわかるといいかなと思うのですが、
Windows の場合はその辺はどうなっているのかわかりませんし、」
という話ですが、Windows でも Unix と同じく
「hostname」というコマンドで一応ホスト名がわかるようなので、
「hostname = system("hostname")
」として
hostname の値で判別すればいいようです。
ただし、system() を使うためには、 gnuplot 4.2 以降が必要ですし、
GUI 版の wgnuplot.exe でこれを行うには、gnuplot 5.0 以降が必要です
(4.X だと wgnuplot.exe ではうまく動かないが gnuplot.exe なら問題ない)。
なお、Windows 上で CUI 版 gnuplot でこれを実行すれば問題はないのですが、
GUI 版 wgnuplot でこれを実行すると、
コマンドプロンプトが一瞬立ち上がってすぐに消えます。
これを避けるには、system() を使わず、ユーザ毎の初期設定ファイル
(Windows の場合は環境変数 APPDATA に設定されるパスの GNUPLOT.INI、
Unix の場合は $HOME/.gnuplot) に、
「hostname="hoge"
」
のように、直接ホスト名を
hostname という変数に代入する式を書いておけばいいでしょう。
ユーザ毎に設定しなくても、
各マシン毎のシステム用の初期設定ファイル (share/gnuplotrc)
にインストール時に書いておけば、
ユーザが設定しなくても使用できるようになります。
それに、この初期設定ファイルに書いておく方法なら、
マシンのホスト名の設定がちゃんと行われていない場合でも
それとは別に gnuplot 的にホストを特定する名前を自由に設定できるので、
色んな環境のマシンがある場合はこの方法が一番楽 (自然) かもしれません。
「情報やメモ (08/29 2016)」 で紹介した、配列を用いた移動平均グラフですが、 複数の変数 (配列を使わない) とカンマ演算子によるサンプルが、 既に demo/ に入っていました。 gnuplot-4.4 くらいから running_avg.dem として含まれています。 サンプルは以下をご覧ください。 後方 5 つ分の移動平均のグラフが書かれています。
「情報やメモ (08/19 2016)」 の gnuplot Q&A 掲示板 の質問記事のまとめの続きです。
昔の gnuplot は、Windows 版の wgnuplot も含めて、 バイナリ本体と 2,3 のファイルだけで閉じていましたので、 それらだけ持ち運べばどこでも簡単に使うことができました。
ところが、今の gnuplot はだいぶおおがかりになり、 いくつかの terminal ドライバが必要とするファイルが 特定のディレクトリに置かれるようになったり、 Windows 版の wgnuplot も含めて多くの共有 (動的) ライブラリ (.dll) が必要になったりしているため、 簡単に 2,3 のファイルを持ち運べば、 という状況ではなくなっています。
そういう外部ファイルを必要とする post, svg, canvas, cairo, lua, qt などの
terminal ドライバを削り、
あるいは post, svg, canvas 用のテキストの外部ファイルは
実行ファイルの内部に埋め込む形にし、
共有ライブラリを使用せず静的ライブラリをリンクするようにする
コンパイルオプション (make target) を設ければ、
可搬な gnuplot を容易に作れるのでは、
ということでそういう質問 (提案 ?) を上げてみました。
(3068 の記事から始まるスレッド
「小さいバイナリ」
2016 02/06: shige)
それに対して、Windows バイナリを作成して配布しておられる 松岡さんから返答があり、 外部ファイルを内部に埋めこむのはコードの変更が必要なので 単純ではない (本家に導入してもらわないといけない) が、 ライブラリの静的リンクを試すことなら可能ということで、 fontconfig の設定ファイルの置き場所に苦労されたようですが、 対話型 terminal は win terminal のみ、 ビットマップ画像は gd ライブラリのみをサポートした版を作って頂きました。
サイズはかなり小さくなっているようですが、 静的リンクのため、本体自体は少し大きめです。 また、fontconfig の設定ファイルが gnuplot バイナリと同じ場所になければいけないため、 そういう制約はあります。
個人的には、fontconfig もいらなくて、 もし fontconfig を切れば wgnuplot.exe, wgnuplot.mnu, wgnuplot.chm の 3 つだけで使えるようになるのですが、 フォントの指定のしやすからすると fontconfig を手放したくない気持も わからないでもありません。
外部ファイルを埋め込んでしまうオプションについては、 post は元々内部に埋め込まれていたわけですし、 svg, canvas が使用する javascript コードを埋め込むのも standalone モードに限定して考えればよくてそう難しくはなさそうなので、 少し時間のあるときに考えてみたいと思います。
グラフの x 軸の刻みのラベルを、データ内にある文字列に置き換えたい、
という質問がありました。
(3100 の記事から始まるスレッド
「目盛見出しを他列の文字で置き換えたい」
2016 03/07: valley さん)
具体的には、
1,2016/01/11 05:10:01,3.1,3.19のように、カンマ (',') 区切りの 4 列のデータが [行番号]、[日時データ]、[y データ 1]、[y データ 2] と並んでいて、 3, 4 列目を y 値とする 2 つのグラフを書きたいが、 2 列目の値を x とするのではなく、等間隔に 1 列目の値を x とし、 その x 軸の刻みに 2 列目の値を使いたい、 すなわち、x 軸の x = 1 の場所には「2016/01/11 05:10:01」と書き、 x 軸の x = 2 の場所には「2016/01/22 06:30:00」と書きたい、 という質問でした。
2,2016/01/22 06:30:00,3.65,3.96
3,2016/01/30 20:30:15,3.89,3.26
4,2016/02/01 18:30:30,3.5,2.69
5,2016/02/10 09:19:00,4.37,4.43
これに対して、
set xtics rotate by -90
plot 'data' using 1:3:xticlabel(2)
のようにすればよい、という回答があり、
質問者もそれでできるようになった、と報告がありました。
x 軸の見出しを変更するには、 通常は「set xtics」で指定するのですが、 データファイル内の文字列を x 軸の刻みラベルに使うには、 「xticlabel(N)」という指定を行います。 そうすると、N 番目の列の文字列を、 それが含まれる行データの x 軸の刻みラベルとして使用します。
データの文字列を使用する方法としては、もう一つ columnhead(N) があります。 これは、データ列の先頭行に各列に対応する文字列を書いておいて、 それを使用するものです。例えば以下のようなデータに対して、
日付 体重 血圧1 列目は上のように x 軸のラベルに使い、 1 行目はグラフのタイトル (key) に使うようにするには、 例えば以下のようにします:
2016/05/01 69.0 120
2016/06/07 70.2 135
2016/07/02 71.3 128
2016/08/10 70.0 138
2016/08/26 70.8 142
set xtics rotate by -30
set grid
set y2tics nomirror
set ytics nomirror
plot 'data' using 0:2:xticlabels(1) w lp lt 7 t columnhead(2),\
'' using 0:3 axes x1y2 w lp lt 6 t columnhead(3)
軸の刻みについては、xticlabels() だけではなく、yticlabel()、 zticlabel() (splot)、x2ticlabel()、y2ticlabel()、cbticlabel() なども実装されています。そのサンプルもついでに紹介します。 例えば、上のデータに対して、yticlabels(1) とすると、 各データの y のデータの箇所に 1 列目の見出しがつきます:
set grid
plot 'data' using 0:2:yticlabels(1) w lp lt 7 t columnhead(2)
同様に yticlabls(), y2ticlabels() を同時に使用することも可能です。
set grid xtics ytics y2tics
set y2tics nomirror
set ytics nomirror
plot 'data' using 0:2:yticlabels(1) w lp lt 7 t columnhead(2),\
'data' using 0:3:y2ticlabels(1) axes x1y2 w lp lt 6 t columnhead(3)
xticlabels() と yticlabls() を同時に使用する場合は、 using 指定に複数書きます。
set grid
plot 'data' using 0:2:xticlabels(1):yticlabels(1)
w lp lt 7 t columnhead(2)
それぞれの違い、特性に合わせて使う必要があります。
さらに、histogram では key(N) という記法を使用して、N 列目を key title に使用することもできるようになっています (demo/ ディレクトリ内の histgrams.dem 参照)。
松岡さんから、いくつか Windows 版 gnuplot、 およびそのコンパイル環境等に関する話が提供されていました。
本家の Bug tracker に載った話ですが、
EMF terminal で Italic 指定したグラフタイトルがうまく Italic にならない、
という報告が松岡さんからありました。
(3123 の記事から始まるスレッド
「emfターミナルでのプロットタイトルに対するenhanced textのバグ」
2016 04/06: 松岡さん)
その辺りの修正は、以前私も関わっていたので、 パッチ等を送ってなんとか修正してもらえました。
ところで、その Bug tracker に載っていた問題を再現するスクリプトが 以下のような書き方になっています (主要な部分だけ、 タイトル部分も除いてある):
plot sin(x)
replot cos(x)
これは、sin(x) と cos(x) のグラフの重ね書きになるのですが、
通常 2 つのグラフの重ね書きは、1 回の plot で
「plot sin(x), cos(x)
」とします。
ところが確かに上の replot を使う方法でも重ね書きされます。
こういう使い方はしたことがなかったので、ちょっと驚きました。
特に、2 つのグラフの色もちゃんと lt 1 と lt 2 と異なる色で書かれ、
key もちゃんと重ならずに上下に並んで表示されています。
「svg, emf」特有の仕様なのか、とか 「undocument な仕様なのでは」などと掲示板では書いたのですが、 ちゃんとマニュアルにも書いてありました。 replot のヘルプに、
「`replot` コマンドに対する引数は最後に実行した `plot` または `splot` コマンドの引数に (暗黙の ',' と共に) 追加され、 それから再実行されます。」とあります。つまり、上の replot を使用する方法は、
plot sin(x)
plot sin(x), cos(x)
とやったことと同じことになっているわけでした。
これは、1 つ目の plot のグラフが描いた直後に
2 つ目の plot (replot によるもの) を実行し、
1 つ目の plot によるグラフの上に重ね書きしていることになります。
つまり 1 つ目の plot が無駄であることになります。
通常の terminal では 1 つ目の plot の直後に 2 つ目のプロットが行われるので、 そういう動作 (1 つ目の plot は無駄) をしていることには気がつきませんし、 結果的には同じものになるので、この方法でも問題はないのですが、 細かく言えば「plot A + replot B」の結果と 「plot A, B」の結果が一致するかどうかは terminal 依存です。 例えば postscript terminal のように、 plot 毎にページを切り替えて出力する terminal の場合、 「plot A, B」の場合は 2 つのグラフが重ね書きされた 1 ページの PostScript ファイルが出力されますが、 「plot A + replot B」だと 1 ページ目は「plot A」による 1 本のグラフ、 2 ページ目が「plot A, B」の 2 本のグラフ、の 2 ページの PostScript ファイルが出力されます。
「plot A + replot B」はスクリプトの見た目が なんとなく綺麗になるという長所もあるので、 上のような仕様であることを知った上で使うのであれば問題はありませんが、 2 本のグラフを書く正しい方法は「plot A, B」 であることをはっきりと認識しておくべきだと思います。
2 ちゃんねるの掲示板「gnuplot を使おう。その 3」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
「gnuplot -e "plot sin(x)"
」とすると
一瞬で終了する、という話がありました (403)。
それに対し、「-persist」をつければよいという回答があったのですが、 -persist だとショートカットキーやマウスでの拡大とかが効かない、 という話もありました。 その方は x11 terminal を使っているということですが、 実は -persist ではマウスの拡大ができない、というのは terminal 依存で、
のようになっています。
散布図を書くのに gnuplot を使っている、 できればクリッカブルマップ的なことができるとうれしい、 という話が書かれていました (414)。
「クリッカブルマップ的なこと」というのは、 想像ですが、グラフ上の指定した場所にマウスカーソルを移動する、 あるいはマウスクリックすると、 それに応じた何かが表示されたりなんらかの動作が行われる、 という仕組みではないかと思います。
グラフ上の特定の場所にマウスカーソルを移動すると、 それに応じたコメントが表示される、という機能は、 現在「hypertext」として実現されていて、 svg, canvas, qt, wxt terminal などで利用できます (gnuplot-5.X 以降)。 例えば以下参照:
特定の場所をクリックしたときに何かの動作を行うという設定も、 「bind "Right"」などにその動作を割り当てておけば 可能です。例:
set xrange [-10:10]
set yrange [-2:2]
# 箱 1, 2 の座標
bx11 = 8.5; bx12 = 9.0; by11 = -1.2; by12 = -1.0
bx21 = 7.5; bx22 = 8.0; by21 = -1.2; by22 = -1.0
# 座標 (x, y) が箱 1, 2 の中にあるかどうかを判別
isinbox1(x, y) = (x >= bx11 && x <= bx12 \
&& y >= by11 && y <= by12)
isinbox2(x, y) = (x >= bx21 && x <= bx22 \
&& y >= by21 && y <= by22)
# マウス左ボタンに箱 1、箱 2 をクリックしたときの動作を割り当て
bind "Button1" "if (isinbox1(MOUSE_X, MOUSE_Y))
{ set grid; replot } \
else { if(isinbox2(MOUSE_X, MOUSE_Y))
{ unset grid; replot }}"
# 箱 1, 2 の描画
set object 1 rectangle from bx11, by11 to bx12, by12 fs solid
fc "red"
set object 2 rectangle from bx21, by21 to bx22, by22 fs solid
fc "green"
plot sin(x)
このサンプルは、右下に赤と緑の箱を表示し、 赤の箱の中でマウスクリックすると set grid して replot、 緑の箱の中でマウスクリックすると unset grid して replot します。
splot で set grid すると変に波打つ、という話がありました (433)。
これは、gnuplot 5.0.0 の gd terminal の点線描画時のバグで、 5.0.1 ではすでに fix されています。 ただ、コンピュータがこういうふらふらな曲線を「ある種の規則に従って」 書くのは珍しいので、なんとなく名残り惜しいようなバグでもあります。 こういうのを改良して、spline ではない妙なふらふらな曲線による補間、 っていう機能を入れてもいいかもしれませんね。
二重ドーナツグラフを gnuplot で作りたい、という話がありました (445)。
URL が示してありましたが ( http://www.becoolusers.com/excel/doughnut-chart02.html)、 「二重ドーナツグラフ」とは、 円グラフの内側が抜かれているドーナツ形式の円グラフを、 外側、内側の 2 重のドーナツの形で 2 つの 100% グラフを書いたもののようです。
これに対して、円グラフを重ねればいいのでは、ということで、 大きな円グラフに中位の円グラフを重ねて、 さらに小さい白円を重ねればいい、 というスクリプトとデータが示されていました。 非常にシンプルで、ほぼ同等のグラフが示されていました。
欲を言えば、その示されていた例は、
という点が少し足りないかなと感じました。
1. の色を元のグラフに完全に合わせる必要は、 もちろん本質的にはありませんが、 現在の gnuplot の機能を使えば、 円グラフの色の指定はかなりカスタマイズできますので、 それを少し考えたいと思います。
また、2. の円グラフのラベルは元のデータに入っているのが自然でしょうから、 with labels を使えばそれをグラフに書きこむことも容易です。 実は回答者のデータにもあるといえばあるのですが、 それを使うことまではしていません。 多分スクリプトとしては本質的な部分だけを示したのでしょう。
3. のグラフのデータが gnuplot 用、というのは、 本来は円グラフのためのデータは、 各項目の割合だけ (38% とか 62% とか) 示されているものだと思いますが、 回答者のデータは、gnuplot の with circle 用に、 それを角に直して開始角と終了角に直してありました。 もちろん、awk などを用いて、 割合だけのデータから gnuplot 用の角のデータに直すことは 難しくはありませんが、 それも多少工夫すれば gnuplot だけで行うことも不可能ではありません。 ただし、スクリプトはだいぶ複雑に、そして汚くなりますので、 どちらの方が良いかは善し悪しがあるかなと思います。
では、元々示されていたグラフに近いものを書く gnuplot スクリプトを以下に示します。 なお、データは外部ファイルではなく、 gnuplot 5.X の機能を使ってインラインデータブロックを使っていますが、 そこをデータファイルにすれば gnuplot-4.6 でも書くことができます。
set term wxt
# 外側のドーナツグラフ用データ (インラインデータブロック)
# [項目名] [百分率] [色の 16 進 RGB]
$OUTD <<EOD
関東 64 0x6ca6cd
関西 36 0x668b8b
EOD
# 外側のドーナツグラフ用データ
# [項目名] [百分率] [色の 16 進 RGB]
$IND <<EOD
神奈川 18 0xcd6839
東京 27 0x8b8970
千葉 19 0xcd853f
京都 8 0x8b7d7b
大阪 28 0xb0c4de
EOD
set size ratio -1
set xrange [-1.2:1.2]
set yrange [-1.2:1.2]
set style fill solid 1.0 border lc rgb "white"
# 三角関数を度単位に
set angles degrees
# 百分率を 360 度に変換
t(x) = 360*x/100.0
# 円グラフの開始角の初期値 (450度 = 90度 = 鉛直上向き)
c10 = 450
c20 = 450
c30 = 450
c40 = 450
# 各半径: rL = 外側ドーナツの外半径、rM = 内側ドーナツの外半径、
rS = 内側ドーナツの内半径、
# rs1 = 外側ドーナツのラベル半径、rs2 = 内側ドーナツのラベル半径
rL = 1.0
rM = 0.75
rS = 0.5
rs1 = (rL + rM)*0.5
rs2 = (rM + rS)*0.5
plot \
$OUTD using (0):(0):(rL):(c11 = t($2), \
c10 = c10-c11, c10):(c10+c11):3 not with circles lc rgb var, \
$IND using (0):(0):(rM):(c21 = t($2), \
c20 = c20-c21, c20):(c20+c21):3 not with circles lc rgb var, \
$IND using (0):(0):(rS):(0):(360) not with circles
lc "white", \
$OUTD using (c31 = t($2), c30 = c30-c31, c31 = c30+c31/2.0, \
rs1*cos(c31)):(rs1*sin(c31)):(sprintf("%s\n%d%%",
strcol(1), $2)) not with labels, \
$IND using (c41 = t($2), c40 = c40 - c41, c41 = c40 + c41/2.0, \
rs2*cos(c41)):(rs2*sin(c41)):(sprintf("%s\n%d%%",
strcol(1), $2)) not with labels
上の plot 行を少し説明します。 1 つ目の plot (plot の 2 行目, 3 行目) は、 外側のドーナツグラフの領域部分を書いています。 using の最初の 3 つは中心座標と半径ですが、 4 つ目と 5 つ目の列が少しややこしいです。 c10 は、各扇形部分の開始角を保存する変数、 c11 は、扇形部分の中心角を保存しています。 using 4 列目で、各行データに対してカンマ演算子 (,) を使って式の計算をやって、その値を次の行に使用するようにしています。 すなわち、「c11=t($2)」で百分率を中心角に直し、 開始角 c10 は c11 を引き算し (円グラフの回転は時計回り)、 c10 から c10 + c11 までの角の扇形を書く、 という手法を取っています。 さらに、その扇形部分の色は lc rgb var と using の「:3」により データの第 3 列から 6 桁の rgb 16 進データを読み込んで使用しています。 なお、この指定は「lc var」と、「rgb」を省略してはいけません。
2 つ目の plot (plot の 4 行目, 5 行目) は、 上と同様にして内側のドーナツの領域部分の描画、 3 つ目の plot (plot の 6 行目) は、 その内側の白い円の描画を行なっています。
4 つ目の plot (plot の 7 行目, 8 行目) は、 with labels による外側ドーナツグラフのラベルの描画で、 各扇形の中心に来るように書いています。 角度の計算は、1 つ目の plot 同様で、開始角と終了角の中心を 「c30 + c31/2.0」で求めています。 with labels は x, y 指定をしないといけませんから、 自前で sin(), cos() を使って座標を求めて描画します。 なお、ラベルは元グラフに合わせて、 「項目名 + 改行 + 百分率」という表示を sprintf() で作っていますが、 そこで 1 列目を文字列として使用するためには strcol() を使う必要があります (直接その列をラベルとして表示するだけなら strcol() なしで列指定だけでよい)。
5 つ目の plot (plot の 9 行目, 10 行目) は、 同様にして内側のグラフにラベルをつけるものです。
なお、カンマ演算子を使う方法は少し厄介ですが、他にも gnuplot 内部で do ループを用いて データを角に加工して一旦 table データとして吐き出してから描画するとか、 CVS 版 (5.1) なら配列を利用するという手もあるかもしれません。
少し質問が明確ではなかったですが、 Excel のデータを gnuplot で処理する場合、 Excel データの出力は MacOS X ではどういう形式が望ましいですか、 という話がありました (475)。
スペース出力データだとだめですよね、 テキストエディタで変更した、 UTF-8 エンコードで改行コードは LF、区切りはタブ区切り、 エンコードは nkf で変換する、 などの話がありました。
まず改行コードは、CR (昔の Mac OS)、CR + LF (Windows)、LF (Unix) などの流儀があります。 現在の Mac OS X がどれが望ましいのかは 私は詳しくはありませんが、Unix 由来の gnuplot は、 LF が含まれている改行コードが実は望ましくて、 古い版では CR だけの改行コードのデータの処理には問題があったことも あったように記憶しています。 ちなみに、nkf を使えば、日本語のエンコードだけでなく、 改行コードの変換もできます。
日本語コードのエンコードについては、 UTF-8 や Shift_JIS を使う場合は、 gnuplot でも「set encoding utf8」「set encoding sjis」 を使う方がいいかもしれません。 EUC-JP を使う場合は、特に問題はないと思いますが、 使用している OS 環境のエンコーディングを使うのが自然です。
フィールドセパレータは、 現在の gnuplot では「set datafile separator」で 指定できますので、 ある程度なんでもよいと思いますが、 gnuplot のバージョンによって多少オプションが違っています。
5 系では、カンマ区切りの指定やタブ区切りの指定の仕方が 4 系と比べて変わっていますし、 5 系では複数文字 (chars) を指定することもできるようになっています。
ただし、個人的にはスペース区切り、タブ区切りよりは、 CSV 形式のデフォルトであるカンマ区切り (,) の方が安全なように思います。
(08/31, 09/02 2016 一部修正 (Thanks 松岡さん))
key の順番を、最後のデータの大きい順に並べ変えできないか、 という質問がありました (481)。
gnuplot では無理、という意見が大半でしたが、 確かに gnuplot にはそのような機能はなく、 通常 plot で指定した順番に key は表示されます。
ただし、現在の gnuplot 5 系では、 「plot title at {beginning|end}」で グラフの端に title を表示できますので、 それがある意味では最後のデータの順番に key を表示する機能と言えなくはないです。
また、現在の CVS 版 (5.1) では、「plot title at」 の後ろに座標 (デフォルトではスクリーン座標系) を指定できるようになりましたので、 これを使えば、plot の指定順を変えなくても key のタイトルの配置を変更することができます。
なお、データの最後の値でソートするという機能は、 どの値を比較してソートするかを指定することが原理的に難しいでしょうから、 実装は難しいと思います。 ただし、plot 順でない順で key を配置するという考え方は面白いかもしれません。 どういう方法が可能か、時間があるときにでも少し考えてみたいと思います。
実は上の「key の順番」という話の回答の中にあった話ですが、 gnuplot はデータ解析には向かない、 移動平均すらできない、という話がありました (486)。
確かに gnuplot は「移動平均」による平滑化機能は持っていませんし、 そういうデータ処理は外部の awk などでやる方が楽ですが、 多少工夫すれば gnuplot だけでやることも不可能ではありません。 それを紹介したいと思います。
(xi, yi) (i=1,2,3,...,n) の n 個のデータに対して、 通常は x = xi に対して、y = yi の値をグラフとして書くのですが、 移動平均はあるサンプル数 N を固定し、 x = xi に対して、yi-N+1 から yi までの N 個のデータの平均を y の値としてグラフを書く、 という手法です。 細かい誤差が多く、 振動が激しいデータの平均的な変動の様子を見るのに使われたりします。 確かに smooth にあってもいいオプション機能かもしれません。
これにはいくつか亜種があり、 例えば過去 (後ろ方向の N 個) の平均でなく、 未来 (前方向の N 個) の平均であったり、 x = xi を中心とする過去と未来から 取ったサンプルの平均とする場合もありますし、 単純な平均ではなく重みのついた平均を考える場合もあります。 また、端のデータについては、 N 個のサンプルが取れない点は捨てる場合もありますし、 取れた分の平均を考える方法や、 取れない過去のデータを仮想的に 0 (またはなんらかの定数) として考える方法などもあります。
ここでは、とりあえず過去の N 個の単純平均とし、 N 個のサンプルが取れない点は捨てる、 という移動平均を考えてみることにします。
移動平均では、 過去の N 個のデータを保持しながらグラフを書いていくことになります。 その N 個の保存用の変数は、 N が小さければ c1, c2, ... などとすることも可能ですが、 現在の CVS 版 (5.1) なら配列変数が利用できるので、 今回はそれを利用することにします。 以下がサンプルスクリプトです。
Maxarray = 100 # 配列の最大要素数
array A[Maxarray]
# A[i] = (i-1) 個過去の値を保持
# SumA(n): A[1] ~ A[n] の和を返す
SumA(n) = sum [i=1:n] A[i]
# 再帰版: SumA(n) = (n <= 1) ? A[1] : SumA(n-1) + A[n]
# PushA(y, n, M): A[1] ~ A[n] を一つずつ後ろにずらして
A[1] に y を追加
# する手続き関数 (返り値は y)、M はサンプル数 (A[M] までを操作)
# 再帰版:
PushA(y, n, N) \
= (n >= N) ? (PushA(y, N-1, N)) :\
(n > 0) ? (A[n+1] = A[n], PushA(y, n-1, N))
: (A[1] = y)
# mean(y, N): 新たな y の値とサンプル数 N から移動平均値を計算
mean(y, N) = (PushA(y, n, N), n = n+1, (n < N)? 1/0 : SumA(N)/N)
plot 'data' using 1:(meanA($2, 3) + 0.6)
t "M=3 (+0.6)" w l,\
n=0, '' using 1:(meanA($2, 6) + 0.4)
t "M=6 (+0.4)" w l,\
n=0, '' using 1:(meanA($2, 10) + 0.2)
t "M=10 (+0.2)" w l,\
sin(x) + 0.1*cos(50*x)
用意したデータは、「f(x) = sin(x) + 0.1*cos(50*x)」という、 sin(x) のグラフに小さいギザギザがついた関数のデータで、 ほぼ 0 から 2π までの範囲を 500 分割したデータです。 サンプル数として 3, 6, 10 の 3 通りの場合の移動平均のグラフを示しています。 そのまま重ねるとギザギザの様子が見えないので、 あえて上下に少しずつずらして書いています (+0.2, +0.4, +0.6)。 サンプル数が大きくなると平滑化効果が強くなって sin(x) のグラフに近くなっていくことがわかりますし、 データは過去のデータがサンプル数になるまで書かず、過去に対して 平均を取りますので、サンプル数が増えるとグラフは その分右に少しずつ平行移動し (ややわかりにくい)、 さらに左端は少しデータが欠けていることがわかるかと思います。
移動平均の計算は、 各データ行毎に、配列の数値を 1 つずらして現在のデータを追加し、 その平均値を求め、それをグラフに書く、という作業を行っています。 A[1] ~ A[n] が過去のデータを保存しておく配列で、 A[i] に (i-1) 番過去の値を保存しています。
SumA(n) は配列の和を求める関数で、 gnuplot の sum (gnuplot-4.6 以降) という命令で求めていますが、 三項演算子を用いて再帰関数として定義すれば sum は必要ありません。
PushA(y, n, N) は、現在の値 y を配列に登録する手続き関数です。 gnuplot には純粋な手続き関数 (返り値のない関数) はありませんが、 同等のものを作ることはできます。 これも三項演算子、カンマ演算子を用いて再帰関数として作成していて、 n は y の登録前までの PushA() の実行回数、 N は最大保存数で、N より多くのデータは保存しません。 返り値としては、一応 y の値が返るはずです。 N には移動平均のサンプル数を指定します。
meanA(y, N) が、現在の値 y に対する移動平均値を返す関数です。 実際には内部で PushA() と SumA() を実行していますので、 この mean() だけを呼び出せばよいようにしています。 外部変数として n (データ番号) を使っています。 これを初期化すれば別なサンプル数に対する移動平均が計算できますので、 上の plot では、新たな移動平均の描画の前に「n = 0」という n の初期化を入れています。 あまり使うことはありませんが、plot 命令には描画する関数やデータの他に、 このような変数の初期化命令をカンマ区切りで書くことができます。
もちろん、smooth などに移動平均が実装されれば楽ですが、 少し大がかりですがこんな風にすれば現在の gnuplot でも 一応移動平均のグラフを書くことはできなくはありません。
(cf. 「情報やメモ (09/08 2016)」)
「情報やメモ (05/30 2016)」 の gnuplot Q&A 掲示板 の質問記事のまとめの続きです。
gnuplot 4.6 で、
key の枠囲みのようにグラフ中の label を枠で囲むことは可能か、
という質問がありました。
(2932 の記事から始まるスレッド
「labelを枠で囲む」
2015 04/02: CANDLE さん)
gnuplot のグラフの「ラベル」というとき以下のように色々な種類があり、 それによって対応が少し変わりますが、 とりあえず不可能ではありません。
ラベルに箱枠をつけたいというのはある程度需要があるのか、 gnuplot-5.0 では多少そのような機能が導入されています。 しかし、上で述べたラベルのうち、 現在の版 (5.0.X) でオプションで枠がつけられるのは 5. の set label と 6. の with labels のラベルのみです。 それらには boxed オプションがついていて、 それを指定することで箱枠がつきます。
それ以外のラベルに箱枠をつけたければ、 set object rectangle などを使って自前で書くしかありません。 座標などは試行錯誤で求めるしかないので、 ラベルが多い場合はかなり大変かもしれません。
ただ、4.6 系では 5., 6. でも boxed オプションはありませんので、 それらは自前で書くしかありませんが、 with labels の場合には、 with candlesticks か with boxxyerrorbars で箱を書いてから その上に with labels でラベルを書く手があります。 実際に回答にもそのようなサンプルをあげました。
元の質問者は時刻を枠で囲んで set label で表示したい、 ということだったようですが、 それは 5.0 を使えば解決しますし、 4.6 でもラベル一つならば set object rectangle でそれほど苦労せずに枠を作れるでしょう。
なお、set title や set xlabel などは boxed オプションが効かないようになっていますが、 boxed オプションが使えるようにするのもそれほど難しくはなさそうなので、 もし良さそうなら少しパッチを考えてみたいと思います。
m 行 3 列の整数値のデータを色に対応させて、
その色の長方形を 3 列に積み上げた 2 次元
heatmap を作りたいのですがどうもうまくいきません、
という質問がありました。
(2939 の記事から始まるスレッド
「2D heatmapの作成」
2015 04/16: valley さん)
かなり詳細なサンプルとデータが記されていましたので、 問題点の再現も容易で、原因はわかりました。 元記事の方は demo/ ディレクトリの、with image によるデモ heatmaps.dem の 4 番目の例が似ているらしく、 それを参考にスクリプトを書いておられたのですが、 heatmaps.dem で使われている rowheaders 指定と、 matrix データの x, y 座標が 0 から始まることが 質問者の想定した出力と合っていない主な原因でした。 rowheaders 指定は一番左の列をラベルと見て無視する指定なので、 データの列が一つずれることになりますからそこに注意が必要です。
さらに multiplot で列毎に描画させていたのですが、 cbrange を指定していなかったために、 autoscale のせいで plot 毎に色の割り当てが変わってしまったため、 すべての列に共通な色の割り当てになっていませんでした。
使用している wgnuplot が 32bit 版のものなのか、
64bit 版のものなのかを簡単に知る方法があるか、
という質問がありました (書きました)。
(2963 の記事から始まるスレッド
「wgnuplot の 32/64 bit 版」
2015 06/18: shige)
gnuplot の対話モードでは、起動時、あるいは「show version」、 「show version long」で バージョンやコンパイルの日付などの情報が表示されます。 また、GPVAL_ で始まる内部変数の値も「show variable GPVAL_」 で見ることができ、それを見れば、 例えば以下のような情報も知ることができ、 さらにそれを gnuplot スクリプト内で参照し、 条件分岐に使用することもできます:
gnuplot の掲示板などを見ると、 Linux と Windows など複数の OS で 1 つの共通の gnuplot スクリプトを使い回している事例もいくつかあるようですので、 その場合、実行している環境、例えば OS 名や OS のバージョン、 ホスト名などを gnuplot 側から取得できれば そのようなスクリプトの条件分岐に使えて便利かなと思いました。 特に、OS によってフォント指定やファイル名、 terminal 名は変更しないといけない場面が多いのではないかと思います。
Unix の場合は、「host = system("hostname")」 とか「host = system("uname")」 とかすればシステムの情報は簡単に取得できるのですが、 それが Windows と共通には使えないので、 GPVAL_ の変数で gnuplot 内部で使えると スクリプトでは便利かなと思います。
そういう点からすると本題の 32bit/64bit はあまり関係ないのですが、 現在 Windows 用バイナリはその 2 種類が公開されていて、 そのどちらを install したかを忘れてしまうと、 現在の wgnuplot がそのどちらだったかを 知ることが簡単にはできなさそうなので、 それは知ることができた方がいいのでは、と思ったわけです。
それに対して、本家のメーリングリストでも活躍しておられる 松岡さんにすぐに反応していただいて、 本家の掲示板 (feature-request) に書いて頂きました。 さらに、 この掲示板の 2990 の記事から始まるスレッド ( 「windows 上での32bitか64bitbかの区別,OS名」 2015 07/02: 松岡さん) で、Windows 版の場合のシステム名等の取得に関する コードの検討とテストが行われました。 それにより、最終的に以下の GPVAL_ 変数が追加実装されました (CVS 版)。
まだ現在の 5.0 系には入っていませんが、CVS 版では使用可能です。 ただし、SYSNAME, MACHINE は実行しているシステムの情報ですが、 BITS は OS の情報ではなく、 現在使用している gnuplot バイナリの、 コンパイル時の情報です。
個人的には、上の情報だけではコンピュータのマシンが特定せず、 複数のコンピュータに同じ OS の別のバージョン、 例えば FreeBSD 9 と FreeBSD 10 のようなものが入っていたりすると その両者で違うフォントを指定しないといけない場合などもあるので、 GPVAL_ でホスト名もわかるといいかなと思うのですが、 Windows の場合はその辺はどうなっているのかわかりませんし、 とりあえずそれは申し出ませんでした。
なお掲示板では、さらに発展して、 Windows 上の 32bit 版のバイナリと 64bit 版のバイナリ (.exe や .dll) を見分けるツール dumpbin.exe の紹介や、 およびそれを利用して簡単なバッチファイルを使っている、 MinGW-W64 の objdump というツールもある、 といった紹介もありました。
Octave の ML が話の始まりのようで、
そこから gnuplot 本家の ML で話題としている内容のようですが、
qt terminal のスピードが遅いことがあるようで、
このスクリプトを qt terminal, wxt 等で試してみてください、
という話が松岡さんからありました。
(2977 の記事から始まるスレッド
「qt terminalのスピード」
2015 06/27: 松岡さん)
環境依存らしいのですが、 松岡さんがビルドしたバイナリではマウス操作で 特に遅くなってしまうそうです。
角藤さんが公開している wgnuplot は qt-5.3.0 を使っていて 角藤さん版では速度には問題はないそうです。 松岡さんのバイナリでは、調べたところ qt-5.3.2 から qt-5.4.2 に上げたら 問題が起きるようになった、ということのようです。
gnuplot のメインの開発者の Ethan Merritt さんは KDE の環境を使っておられるようで、 となると Qt が自然に使える状況なのでしょうが、 Qt ライブラリは相当巨大なので、 Windows 環境でも Unix 環境でも 自前でコンパイルしてそのライブラリをこしらえるのは 容易ではありません。 しかも、うちでもあまり安定して動作してくれなくて、 ある時期の gnuplot から (だったか qt4 から qt5 に変えたころだったか) 相当 qt terminal が不安定になり、 今はあまり使いものになりません。
qt terminal は、Ethan さんが継続してずっと手を入れていて、 「情報やメモ (05/09 2016)」 にも書いたようにある環境では default terminal にもなり、 一応はマルチプラットフォームなものなのですが、 個人的には、デフォルトで KDE を使っている人以外には あまり便利な環境ではないように思いますし、 wxt terminal と比べても良さがあまり感じられないように思います。
with point の点種 7, 9, 11 のように塗り潰しの丸 (●) や三角 (▲)
がお互いに重なる場合、
重なりがわかるような描画の仕方は可能でしょうか、
という質問がありました。
(3020 の記事から始まるスレッド
「塗りのあるプロットの枠だけ白くしたい」
2015 09/03: 手歩進 さん)
具体的には、図の提示があったのですが、 それとほぼ同等の図を以下に示します。
普通に plot すると 1. のようになり、 2. のようになってもらいたいと思って 同じ形の点で塗り潰しがない点種を境界の代わりに重ね書きすると、 3. のようになってしまう、 という話でした。
plot の実行例がなかったのですが、例えば、
0 0
1 1
2 0
3 1
のようなデータ data に対して、
# [ア] 赤円板●と白円周○を書く
sp = 4
set xrange [0-sp : 3+sp]
set yrange [0-sp : 1+sp]
unset key
plot 'data' with p ps 20 pt 7 lc 'red',
'' with p ps 20 pt 6 lw 3 lc 'white'
とすれば上の 3. のようなグラフが書けます。
これは、赤で一度書いた塗り潰しの丸 (pt 7) の上に、
白で塗り潰さない丸 (pt 6) を書いているのですが ([ア])、
これでは確かに 3. のようになります。
plot コマンドで重ね書きをすると、
まずすべての点に対する赤丸が書かれ、
その後ですべての点に対する白丸が書かれるからです。
2. のようにしたい場合は、赤丸、白丸、赤丸、白丸、
のような順番に書かないといけないわけですが、
デフォルトではそうならないわけです。
なお、このような境界付きの丸は、pt 7 と pt 6 の組み合わせでなく、 pt 7 の丸だけでも書くことができます。 つまり、白の塗り潰しの少し大き目の丸の次に、 赤の塗り潰しの少し小さめの丸を書けばいいわけです ([イ])。 例えば以下の通りです。
# [イ] 白円板●と一回り小さい赤円板●を書く
sp = 4
set xrange [0-sp : 3+sp]
set yrange [0-sp : 1+sp]
unset key
plot 'data' with p ps 20 pt 7 lc 'white',
'' with p ps 19 pt 7 lc 'red'
ただし、このままだと、これは白丸を全部書いた後で
赤丸を書くので、1. のような図になります。
それに対して、2. のグラフを実現する 3 通りの方法を紹介します。
set multiplot
do for [i=1:4] {
# [イ] の方法で
plot 'data' every ::(i-1)::(i-1) with p
ps 20 pt 7 lc 'white',\
  ;'' every ::(i-1)::(i-1) with p
ps 19 pt 7 lc 'red'
# または [ア] の方法で
# plot 'data' every ::(i-1)::(i-1) with p
ps 20 pt 7 lc 'red',\
# '' every ::(i-1)::(i-1) with p
ps 20 pt 6 lw 3 lc 'white'
}
unset multiplot
これは、every で 1 点の円と円周だけを順番通りに書いて、 それを multiplot ですべて重ねる、という方法です。 これで白、赤を交互に書けます。 なお、do for の最後の数字 4 は点の個数ですが、 それは事前に stat などで取得しておく必要があります。
set style fill solid 1.0 border lc 'white'
plot 'data' using 1:2:(1.0):(0):(360) with circles lc 'red' lw 5
これは、円の形しか書けませんが、 現在は with circle で各点に円を書くことができるようになっていて、 それならば境界線の設定も可能だし、 円板と円周をセットで書けるので、自然に赤、白が交互に書かれます。 using の 3 つ目の 1.0 は円の半径、 lw 5 は円周の線幅の指定です。
set style fill solid 1.0 noborder
rad(j) = 1.0 + (2-j)*0.1
lc(j) = (j==1)? 65536*255+256*255+255 : 65536*255
plot for [i=1:5] for [j=1:2] 'data'
using 1:2:(rad(j)):(0):(360):(lc(j)) \
every ::(i-1)::(i-1) with circles lc rgb var
これは、上の with circle の方法で [イ] を実現するようなもので、 白丸と少し小さい赤丸を for の入れ子を使って交互に書いています。 rad(j) は j (1 or 2) に応じて半径を大小に変更する関数、 lc(j) は rgb variable に渡す 24bit 色値で、 j=1 のときは白、j=2 では赤となるようにする関数です。
3 番目よりは 2 番目の方が易しいですが、 これらの方法はいずれも円にしか使えません。 よって、四角形や三角形などの記号を使う場合は 1 番目の multiplot を使う方法しかありません。 1 番目の方法で、四角形や三角形の結果のグラフを以下に示します。
質問者も言っていましたが、長所・短所はそれぞれあるので、 適宜使い分ける必要はありそうです。
2939 の記事から始まるスレッド
でデータを長方形の積み上げ式で色で表現したいという
質問をされていた方から
その長方形に枠線 (grid) を書きたいのだがうまくいかない、
という追加の質問がきました。
(3027 の記事から始まるスレッド
「2D headmapで各マスへ枠線描画」
2015 10/16: valley さん)
具体的には、そのスレッドで作成した (2946 番の記事) のは 以下のようなグラフです:
元記事の方は、ytics, mytics を設定し、 set grid したんだけどうまくいかない、ということでした。
実際、 2946 の記事 に書かれているスクリプトに、質問者の言われるように
set ytics 1
set mytics 2
set tics scale 0, 0.001
set grid noytics mytics front lw 1.5 linetype -1
のようなものを追加しても、grid が何も表示されません。
なお、「set ytics 1; set mytics 2」として「set grid noytics mytics」
としているのは、grid を引く場所のためです。
このグラフの長方形は、
ytics のラベルが matrix rowheaders のため文字で表示されていますが、
実際には長方形の中心が 0, 1, 2, 3, 4, 5 という整数値なので、
grid は y 座標の 0.5, 1.5, 2.5, 3,5, 4.5 といったところに
書きたいわけです。
それなら、最初から
set ytics 0.5, 1
set grid ytics front lw 1.5 linetype -1
として ytics の位置を 0.5 から 1 刻み、
とすれば良さそうに感じるかもしれませんが、
こうすると以下のようになります:
grid が長方形の中心を通ってしまっていますが、 これは「set ytics 0, 1」としても変わりません。 これも原因は実は matrix rowheaders です。 実際、rowheaders の使用をやめれば、 最初の ytics + mytics の設定でも、 ytics 0.5, 1 の設定でもうまく行きます。
これは、gnuplot のソース (src/datafile.c) を見てようやくわかりましたが、 実は rowheader の場合は、ytics の計算は自前でやっていて、 明示的な set ytics 指定と同様の状況になっているようです。 その ytics は長方形の中心で (label のある場所)、 それらの座標は 0, 1, 2, 3, 4, 5 という整数値になっています。 それで ytics を有効にした grid を書くと 中心に長方形の中心に線が書かれてしまうわけです。
最初の例がうまくいかないのは、 明示的な set ytics に対して増分形の「set ytics」 を行っても無視されるからで、 そしてそれが設定されない以上「set mytics」 の設定も無効になるから、と考えればよさそうです。
では、rowheaders の場合どうすればいいかといえば、 「set ytics 1」の代わりに、 「set ytics add 1」のような add オプションを使えばいいようです。 これで ytics の増分系の tics が有効になりますから、 set mytics の設定も有効になって、 mytics への grid が書けることになります。
なお、mytics を使わずに「set ytics add 0.5, 1」として ytics への grid を書こうとすると、 rowheader で設定されている ytics が依然有効なので、 長方形の中心線も書かれてしまうことになります。
ということで、add だけ追加した以下でほぼうまくいきます:
set ytics add 1
set mytics 2
set grid noytics mytics front lw 1.5 linetype -1
ただし、2 つ問題があります。 ひとつは、autoscale のせいで y の上端が 6 まで伸びてしまっていること、 もう一つは長方形の中心に ytics の刻みが書かれてしまっていることです。 前者は、ytics の終了値を明示して「set ytics add 0,1,5」とすればよく、 後者は、存在はするが見えないくらいの大きさにする、 という「set tics scale 0.001」を指定するとうまくいきます。 しかし、「set tics scale 0.001」は 「set ytics add」より前に設定しないとうまくいかないようで、
set tics scale 0.001
unset xtics
set ytics add 0, 1, 5
set mytics 2
set grid noytics mytics front lw 1.5 linetype -1
としてうまくいったようです。なお、tics scale は、
set ytics にもつけられるのでそちらにつけることも可能です。
しかも、そうすれば unset xtics する必要もなくなり、
set ytics add 0, 1, 5 scale 0.001
set mytics 2
set grid noytics mytics front lw 1.5 linetype -1
でうまくいきます。
この辺は、gnuplot のマニュアルにはドキュメント化されていない話だと思いますが、 set tics scale の指定の順番なども含めて、 いずれもちょっと厄介ですね。
グラフのタイトル (set title の文字列)
をデータファイルの情報、例えばコメント行に書いた文字列などから
タイトル文字列を作りたいのですが、という質問がありました。
(3033 の記事から始まるスレッド
「データファイルに変数を格納し読み出す方法」
2015 10/29: せつ さん)
データファイルから文字列を読み出す機能は、 gnuplot 本体では、xticslabels(), columnheader(), rowheader(), with labels などがありますが、 それはいずれも plot 時に実行されるものなので、 グラフタイトルとして使うことはできません。
ひとつの解決策は、 awk などの外部プログラムを使って読み出す方法ですが、 元記事の方は一つのデータファイルに 複数の index データが含まれるデータファイルを提示していて、 その index データの先頭のコメント行から文字列を読み出す、 といったことを想定しておられるようです:
#y=0のようなデータファイル data に対して、 各 index の 1 行目を読み出して set title で使用し、 2 行目を読み出して plot title (plot ... title) で使用する、 ということをしたいようでした。
#t=4
#x f
0 0
1 1
#y=1
#t=8
#x f
0 3
1 4
...
ひとつの解決策は、awk のような外部プログラムと system() を利用する方法です。 最近の gnuplot では、system() で外部プログラムを呼び出して、 その標準出力文字列を値として取得できます。 例えば各 index データのヘッダが 3 行とわかっていれば、
set xrange [-1:2]
set yrange [-1:5]
do for [i=0:1] {
s1 = system(sprintf("awk
'/^#/ && ++N == %d \
{print substr(\$0,2)}'
data", 3*i + 1));
s2 = system(sprintf("awk
'/^#/ && ++N == %d \
{print substr(\$0,2)}'
data", 3*i + 2));
set title s1
plot 'data' index i t s2 w lp
pause 3
}
のようにすればいいわけです。
ただ、awk を利用できる環境があるならば、 逆に awk から gnuplot を awk のパイプを利用して gnuplot を実行する手もあります。 awk の方がプログラムの構文は豊富ですし、データ処理も容易なので、 awk の構文に馴れているならそちらの方が楽だし高機能だと思います。 ただし、環境によってはパイプ経由での gnuplot の実行が使いにくい場合もあります。 その場合は、awk で gnuplot スクリプトだけ作成して、 それを awk の外で gnuplot に食わせる、という手もあります。 もちろんこれらは awk でなく、perl などでも結構です。
もう一つの手ですが、 もしデータファイルから取得したいのが 上のように数値だけなのであれば、 stats でも読み込むことが可能です。 その場合、ヘッダの情報をコメント行ではなく 数値として 1 行目に書いておくことにして、 グラフの方は 2 行目から読むようにします:
# 先頭行はヘッダ (y, t)これに対して、以下のように stats を使って 各 index データの 1 行目だけを読み (every ::0::0)、 plot では逆に各 index データの 2 行目以降だけを読みます (every ::1)。
# 2 行目以降が (x, f)
0 4
0 0
1 1
# 先頭行はヘッダ (y, t)
# 2 行目以降が (x, f)
1 8
0 3
1 4
...
set xrange [-1:2]
set yrange [-1:5]
do for [i=0:1] {
stats [0:1][4:8] 'data' index i
every ::0::0 using (y=$1):(t=$2) noout
set title sprintf("y=%d", y)
plot 'data' index i every ::1
t sprintf("t=%d", t) w lp
pause 3
}
stats の using 命令を使って
y, t という変数にその数値を取得しています。
その数値から sprintf() で必要なタイトル文字列を作ればいいので、
数値でよければこのような手法が可能です。
ただし、stats で 1 行しかデータを読まない場合、
「Warning: Can't compute errors of slope and intercept.
Not enough data points.」のような警告がでます。
(cf. 「情報やメモ (08/31 2016)」)
前回の報告 (06/13 2016)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
最近、かなり修正作業がたくさん入っていて、報告が追いついていません。 この中で、注目すべきものを上げると以下のような感じでしょうか。
1. は、精力的に改良を続けておられる Bastian Maerkisch さんの作業で、 win 回りの Unicode 処理、GDI+ 対応などの大がかりな改良が行われ続けています。 私は最近は Windows 版の gnuplot, wgnuplot を自前で make していないので、 実際どのようになっているのか確認できていませんが、 色々な改良が行われているようです。 グラフをビットマップに保存する機能は、wxt terminal などにはありましたが、 今度は win terminal にもつくようで、 GIF, PNG, JPEG の画像が set terminal を切り替えなくても作れたり、 TIFF 画像や BMP 画像出力も他のソフトなどを経由せずに 直接作れるようになるようです。
2. の負の増分の iteration は、例えば「plot for [i=9:1:-1]」で i=9 の一つのグラフしか出なかった問題の修正のようです。
3. は key の調整機能です。 key は、自動でやってくれよと思うこともありますが、 色々手動で細かい調整が行えるといいなあと思うことがありますので、 そういう需要に答えたものでしょうか。 今後も少しずつこのようなものが追加されるかもしれません。
4. は、with labels や set label で使える枠 (textbox) の属性の設定 set style textbox で、 従来「{opaque|transparent} {{no}border}」の設定だけだったものが、今回
set style textbox {opaque|transparent} {{no}border {<bordercolor>}}
{fillcolor <color>}
{margins <xmargin>,<ymargin>}
と、枠の色、中の塗り潰し色、マージンの設定などが行えるようになりました。
塗り潰しは、terminal がサポートしていればアルファ成分も指定できるので、
網掛けみたいな感じにもできそうです。
5. は、with labels の using で追加列を与えて「rotate variable」 によって個々の文字の回転角を変えたり、 「textcolor variable」で個々の文字の色を変えたりできるようにするものです。 今までも variable による色の変更はありましたが、 今回回転角の個別指定が可能になりました。 以下にサンプルデモがあります。
6. は、set minussign で、負の符号用の「-」の文字を変えるものです。 通常、負の符号はハイフン (-) が使用されていますが、 表示の際にはマイナス記号 (−) が望ましい場合があるようで、 set minussign とすることで、encoding の設定に従って 負の符号がハイフンからマイナス記号に切り替わる機能が今回実装されました。 出力される文字と encoding の関係は以下のようになっています。
これはまだ試験的な実装で、sjis の場合はまだ問題がある、という報告もあります。 なおこれは、gprintf() という関数で生成される文字列にしか 影響を与えませんので、軸の刻みのラベルと、 gprintf() を明示的に使用して生成した文字列のハイフンにしか その変換は行われない、ということになっているようです (少なくとも今のところは)。
また、LaTeX 系 terminal では、負符号の処理は LaTeX 自身が行いますので、 set minussign の設定は無視されることになっています。
私も一度どこかでそのような話、すなわち gnuplot の負符号が ハイフンで表示されてしまっている、という話題を目にしたことがあります。 個人的にはあまり気にしていませんでしたが、 そういう需要もあるようですね。
07/21 頃に、gnuplot-5.0.4 が公開されました。 5.0.4 での新規機能、変更、修正は以下のようです。
5.0.1, 5.0.2 での修正は相当に多く (cf. 「情報やメモ (06/22 2015)」, 「情報やメモ (02/05 2016)」)、 5.0.3 は、5.0.2 の緊急パッチだったので修正はあまりなかったのですが (cf. 「情報やメモ (02/23 2016)」)、 また今回の 5.0.4 でも少し多めの修正が入っているように思います。 5.0 系の大きな変更のためでしょうか、安定性が良くないのかもしれません。 となると、5.2 のリリースは少し先に伸びるかもしれませんね。
前回の報告 (05/10 2016) で一旦切った、 04/27 の後に現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回の改良、修正では、前回の方向で紹介した 「非線形軸」に関するもの、 および「Windows 上の gnuplot (wgnuplot) の Unicode 対応」 がかなり大量に入ってきています。 それと関連して、readline 周りの修正、GUI 部分の修正なども追加されています。 前者に関しては、特に、従来の対数軸も内部的には この「非線形軸」を使って実装されることになり、 それに伴う修正などもありました。 よって、今後は対数軸に関する挙動が、 従来のものと少し変わる可能性があります。
その他には、以下のものをあげておきます。
1. は、多分 svg での standalone モードの際は、出力する svg 以外には 外部画像ファイルを使用せずに済ませるためのものだと思います (未確認)。
2. は、x11 出力で日本語を使っているときに set label で boxed をつけるとグラフウィンドウが落ちていた問題の修正です。これで、 日本語の set label も boxed オプションで枠がつけられるようになります。 なお、set title や set xlabel などのラベルも boxed オプションを使えるようにすることはそれほど難しくなさそうなので、 そのうちにパッチでも作ってみようかと思っています。
3. は、 gnuplot QandA の 3140 で話題になっていた話で、多少改良がなされています。
4., 5., 6. はコマンドラインの編集機能に関する修正、変更 (gnuplot の組み込み readline) で、 編集コマンドに使われる文字を入力する場合はその前に C-V を打つとか、 C-R/C-S を検索機能の方で使えるようにするとか、 GNU readline に合わせた改良がだいぶなされています。
7. は、従来の set table は上書き出力しかなかったのですが、 新設された append オプションにより追加出力をすることが可能になりました。 ただし、あくまで append、すなわち「行」データとしての追加出力であり、 paste のようにデータの「列」としての追加出力ではありません。
(cf. 「情報やメモ (08/10 2016)」)
「情報やメモ (05/17 2016)」 の gnuplot Q&A 掲示板 の質問記事のまとめの続きです。
gnuplot の 5.0rc1 版で日本語フォント指定でサイズ指定が効かない、
フォントが効かない、などの問題があることに気がついて、
いつからこういう問題が起きているのか、QandA に投稿してみました。
(2889 の記事から始まるスレッド
「5.0rc の win terminal の日本語フォント」
2014 12/17: shige)
kakuto さんとのやりとりで、色々な問題点が明らかに、 そして明確になり、最終的には本家に報告して無事 CVS 版、 5.0rc 系ツリーで修正されました。 kakuto さん、どうもありがとうございました (cf. 「情報やメモ (01/06 2015)」)。
win terminal で plot で lt を指定しても、
点線にできない、lt 0 だけが点線で、
1 以降の lt は全部実線になってしまいます、
という質問がありました。
(2914 の記事から始まるスレッド
「線種の変え方」
2015 01/16: CANDLE さん)
gnuplot 5.X では、set terminal の dashed オプションは廃止され、dashtype (dt) で plot コマンドに直接指定して グラフ毎に実線/点線/破線を指定できるようになりました (cf. 「情報やメモ (04/28 2014)」)。 よって gnuplot 5.X では plot コマンドのオプション指定の方を変更する必要があります。
元記事の方は、4.X を利用されていたようで、 「set terminal windows dashed」で解決したようです。
高解像度の画像を作るため、
win terminal で大きなサイズのウィンドウを開いて
それをクリップボードにコピーしてペイントに貼りつけて
PNG として保存しているのですが、
set term で指定したサイズよりも小さなサイズになってしまうのですが、
という質問がありました。
(2919 の記事から始まるスレッド
「画像の出力サイズ」
2015 01/18: CANDLE さん)
具体的には、「set term win size 1350, 900」として画像を作ると 1334x832 pixel になる、ということでした。 また、「set term png size 1350, 900」とすると 1350x900 pixel になるが、解像度が悪い、という話もありました。
実際には質問者が自己解決し、 win terminal のタスクバーや枠のサイズも含まれていたために その分小さくなっていたので、 「set term win size 1366, 986」とすれば 1350x900 pixel とできた、ということでした。
最終結果を PNG 画像として欲しいのであれば、 wgnuplot だけで済む他の手段もあります。 「set term png」の解像度が悪い、 というのは多分それは gdlib 由来の png terminal だと思いますが、 もう一つ png を出力する pngcairo terminal があります。 そちらの方がやや綺麗にでます。
もう一つは、wxt terminal での file export 機能で、 今の export 機能では PNG 出力も出せますが、 gnuplot 5.0 以降が必要かもしれません。 ただ、win terminal の画像のスナップショットが必要、 ということなら確かに質問者の方法になるかと思います。
sample の値を大きくして PDF や EPS や SVG
のようにベクター画像形式で出力したものを
inkscape や illustrator で拡大すると
滑らかには表示されず「かくかく」してしまいます、
という質問がありました。
(2922 の記事から始まるスレッド
「ベクター画像出力する際の描画精度を上げたい」
2015 02/01: 手歩進 さん)
例えば以下のようなスクリプトで作ったものを inkscape で開いて拡大すると点が直線上に乗ってない、 という例がありました。
set term svg
set out 'out.svg'
set sample 1000
plot x with linespoints pt 7 ps 0.03 lw 0.1
このグラフは linespoints なので、本来は点と線で構成されているのですが、
点は塗り潰した丸 (pt 7) で、そのサイズはかなり小さく指定され (ps 0.03)、
線幅もだいぶ細く指定されています (lw 0.1) が、
それは sample 数を通常の 10 倍 (set sample 1000)
としていることのためだと思います。
単純に「sample 1000」とだけするとびっしり点が並ぶことになるので、
普通の大きさの点だとほとんど重なってしまいます。
そこで点の大きさが重ならないように点を小さくすると、
線幅も細くしないと今度は線幅に点の記号が埋まってしまいますので、
線幅も細くしているわけなのでしょう。
しかしこの状態だと、 通常のサイズのグラフでは点は点の記号としてはほとんど見えず、 ほぼただの線として見えてしまいます。 この「ps 0.03」の点を記号として認識するには、 図自体をかなり拡大しないと見えません。 実際、質問者が「かくかく」 しているサンプルを画像として示していたのですが、 それは元の画像を多分 10 ~ 100 倍くらいしたものの話で、 その位拡大すると確かに「かくかく」はして見えます。
それに対して、ベクトル画像は拡大しても汚なくなるわけではないが、 点の配置座標には有限の精度があり、 その丸め誤差のために拡大すればかくかくするのは仕方がない、 むしろ「set sample 100」とすればかくかくはしないだろう、 という意見がありましたが、 5 ~ 10 倍程度の拡大でもかくかくしてしまう、 という反論がありました。
それに対して、目的は何なのかを明確にした方が適切な回答がつくのでは、 EPS や svg ファイルの座標の精度は 4,5 桁なので、 拡大すればかくかくするのは当然、 terminal のオプションとして size 指定を大きくすれば 相対的に精度は上がることになる、という回答がありました。 質問者は、PDF にベクター画像を貼り付けて使うが、 その PDF のビューアの最大拡大率にすると歪みが見えた、 電子ファイルでそのファイルを提出するので、 相手がいくら拡大しても歪まないような描画精度が欲しい、 という話のようでした。 そして、描画エリア (terminal の size) を広くしたら 確かに描画精度が上がった、という話がきていました。
post terminal の場合は、 post.h のソースを 4 箇所いじって自分でコンパイルすれば post terminal の精度は簡単に上げることができる、 という話も追加で上がっていました。
svg terminal のデフォルトのサイズは 640x480 で、 その座標の精度は「小数 1 桁」に固定されていて、 精度は最大で 4 桁となります。 よって、size オプションで大きな数値を指定するしか 精度を上げる方法はありません。 もちろん、term/svg.trm を修正して 自前でコンパイルすれば精度は上げられますが、 そのように精度を上げても その出力を周辺のソフトがどれくらい対応できるかは不明です。
どういう目的の資料かはわかりませんが、 逆にどんなに拡大してもかくかくしないようなデータは、 データサイズもかなり大きくなりますし、 コンピュータのデータである以上 拡大してかくかくするのは決して不自然ではなく、 ある程度は仕方はないと思います。 set sample 1000 の元での point は、 そもそもかなり拡大しないと point に見えないわけで、 むしろ普通のサイズでそう見えないようなグラフを with linespoints で書くことの方が個人的には不自然に感じます。
gnuplot 5.X の gd terminal driver (libgd 由来の png/gif/jpeg terminal)
で点線/破線の描画にバグがあるらしい、
2
ちゃんねる (433)、
ネット上の質問サイト (stackoverflow)、
本家の bug tracker
などで見受けられるがまだ解決されていない、という報告がありました。
(2929 の記事から始まるスレッド
「gd系ターミナルの破線のバグについて(Ver.5)」
2015 02/18: 松岡 さん)
Bug tracker の方に記事を載せたのは私なのですが (cf. 「情報やメモ (01/30 2015)」)、 その後問題点も見つかり、その対応の patch が本家に採用されました。 gnuplot-5.0.1 以降は問題は解消されています。
(cf. 「情報やメモ (08/19 2016)」)
「情報やメモ (05/09 2016)」 の gnuplot Q&A 掲示板 の質問記事のまとめの続きです。
(当時の) CVS 版 gnuplot の Windows 上の qt terminal
で標準入力を読めない問題がある、という報告がありました。
(2797 の記事から始まるスレッド
「qt terminal on windows における標準入力」
2014 06/13: kakuto さん)
自前のパッチも報告し、 また本質的な問題点に気がついた旨の報告もありましたが、 松岡さんが本家の方に報告したことなどもあり、 現在の開発主要メンバーの B.Maerkisch さんが気づかれて修正されたそうです。
対話型 terminal では、
グラフウィンドウ上でいくつかのキー操作が可能になっていますが
(help bind 参照)、
space では通常 gnuplot のコマンドウィンドウ (console window)
が上に出る (raise) ことになっているのですが、
それが wxt で動かないことがあるという話題が gnuplot ML に出ていたそうです。
そこで調べてみると、どうやら qt では全く機能しない、
という質問がありました。
(2804 の記事から始まるスレッド
「qt terminalでのスペースキーでのコマンドウィンドウのraiseについて」
2014 06/19: 松岡さん)
qt terminal のソースを調べると、 どうやらその機能は実装していないようです。 少なくともその時点では、pm (OS/2), x11, win, wxt だけが実装していたようでした。
ただ、qt terminal のドキュメントには space で raise すると書いてあるが、それはバグになるのでは、 だから実装するか、 マニュアルの記述を削除するかしないといけないのでは、 という追加の話題もありました。 これはありがちの話なのですが、qt terminal のマニュアルは wxt あたりのマニュアルを流用して書いていて、 多分実装していない部分を確認せず、 消し忘れているんだと思います。 とりあえずは消すのが筋だと思いますが、 簡単に実装できるならそれもありでしょう。 ただ、松岡さんが ML や本家の bug の掲示板でも議論しておられたようですが、 どうやら qt の場合は簡単ではなさそうです。
さらに、'q' でグラフウィンドウが閉じる機能も 多くの対話型 terminal でサポートされていますが、 win terminal でそれがサポートされていないこともわかったそうで、 それも閉じるように修正されたそうです。
gnuplot (gnuplot-4.5.5 for Windows 7) の int() で、
int(0.1/0.1), int(0.2/0.1), int(0.3/0.1), ..., int(1.0/0.1)というものを計算させると、「1, 2, 3, ..., 10」ではなく、 「1, 2, 2, 4, 5, 5, 6, 8, 9, 10」となってしまう、 という質問がありました。
実数計算だと誤差が必ずあるので、そういうことが起こりうる、 それを避けるには「int(0.3/0.1 + 0.1)」のようにするとよい、 という回答がありました。
また、「int(0.3/0.10)」のようにするだけでも回避できるのでは、 という回答もありましたが、処理系依存らしく、 例えばうちの FreeBSD + gcc で作った gnuplot では解消しませんでした。
さらに int() 以外に「ちゃんと丸め」る関数もあるのでは、 という話も出ましたが、 gnuplot では実数から整数への変換関数としては、 以下の 3 つしか提供しておらず、 いわゆる最近接丸めである round() がありません。
これに対して gnuplot にはない round() は、 round(3.4) = 3, round(3.9) = 4, round(-3.4) = -3, round(-3.9) = -4 となる関数で、 四捨五入に近いものになります。
round() や rint() があるといいでしょうね、 という話が松田さんからもありました。 round() とほぼ同様の関数に rint() なるものがあるのですが、 細かい話をすると整数と整数の「丁度真ん中」 の実数に対する対応が、rint() と round() では違っていて、 例えば、デフォルトの状態では、 「round(3.5) = 4, round(2.5) = 3, rint(3.5) = 4, rint(2.5) = 2」 となったりします (round(), rint() の詳しい話は、各処理系の round(), rint() のマニュアルなどを参照)。
松田さんは、round() を gnuplot に実装するのはそう難しくないのでは、 ということでそういうパッチも作成してみて気がつかれたようですが、 round() という関数自体どの環境にも用意されているわけではなく いわゆる C99 の関数なので、例えば Solaris 9 とか、 少し前の MSVC とかでは用意されていませんでした。 以前、gnuplot でも内部処理に round() を使ったコードが入ったことがあったのですが、 それがコンパイルできずにまたそうでないコードに戻されました。 ということで、round() を導入するとしても、 そういう環境用に round() の emulation (例えば x>=0 なら floor(x + 0.5), x< 0 なら ceil(x - 0.5) とか) の代用が必要になります。 ただ、round() はあると便利なので、 時期を見て本家に導入を提案してもいいかなとは思います。
splot のブロックデータが別々のファイルに保存されているときに、
それを読み込んで一つのデータの多ブロックデータとして扱って
splot のグリッドを構成させることはできませんか、
という質問がありました
(多分だいたいそういう話だったと思います)。
(2829 の記事から始まるスレッド
「splot で複数ファイルのデータをグリッドデータとして扱う方法」
2014 08/20: nkom さん)
どうも話からして、 それらのファイルを単に行として 1 行の空行を挟んで連結したデータファイルにすればよさそうなんですが、 splot の for ではうまくいかない、 別なソフトで前処理はせずに gnuplot だけでできるとよいのだが、 という話でした。
また、Glob パターン (ワイルドカード) でファイルのリストが作れるといいのだが、 Unix (Cygwin) 環境で ls でもできるが、 Windows 環境でも同じスクリプトが使えるといいので、 gnuplot でできるといいんじゃないか、 という追加の質問 (要望 ?) もありました。
複数のファイルのデータを 1 つのデータとして扱う方法は、 現在の CVS 版なら配列を使えばなんとかならなくもないですが、 少なくとも当時は gnuplot の機能としてはありませんでした。 for 文でもできません。 system() を使って、 外部に別なファイルを作るのであれば可能ですが、 gnuplot 内部の機能としては無理です (でした)。
ただ、行データとして連結するだけなら、 Unix でも Windows でも 外部のシステムコマンドを使って簡単にできるので、 system() (または !) でつなげてしまえばいいような気がします。 それは gnuplot スクリプトにちゃんと書けます。 いっそ gawk とか使えば Windows だろうが Unix だろうが同じスクリプトを書くことも可能です。
元記事の人は、gnuplot にそういう機能がないなら、 CVS 版のソースを調べてみる、ということで、 データファイルを読んだときに ファイルの終わりになったことを空行 1 行あったと見なすようにすればよさそう、 とか、いくつかの改善の方法の提案をしておられました。 gnuplot はオープンソースなので、 必要な機能があれば自分で実装して自分用の gnuplot を作ることも可能ですし、 他の人にも便利だろうと思えば 誰でも本家にその修正投稿して、 こんなんどう、と提案することもできます。 そういうところがオープンソースソフトの醍醐味です。
松田さんも、 指定ファイルに '< cat *.dat' のように パイプ入力機能を使えば連結データを直接グラフに出せる、 という例を提示しておられましたが、 結果として元記事の方は、 python と expect と gnuplot でやることにした、 ということのようでした。 確かに python や perl のようなスクリプト言語なら、 内部にプラットフォームに依存しないファイルリスト、 Glob パターン、シェルコマンドの実行などの機能を 持っていますから、 gnuplot スクリプトと gnuplot の機能だけに固執して 超絶技巧を凝らすよりも、 外部のスクリプト言語と連携して gnuplot にない機能を補うやり方の方がむしろシンプルで、 応用も効くと思います。
私も、普段は直接 gnuplot スクリプトを書いているのではなく、 シェルスクリプト (C-shell script) を書いていて、 その中で awk スクリプトや gnuplot スクリプトを ヒアドキュメントとして書いて実行することが多いです。 だから、あまり gnuplot 内部にすべての機能が 収まっていなくても不満には感じませんが、 Unix と Windows でスクリプトを共有したい人 (私はそうではない) は gnuplot で共通した機能が欲しい、 と感じているのかもしれませんね。
なお、この話題からいくつかの話が派生しました。 expect って何、ということから、 expect は対話型処理を自動化するもので パスワード入力の自動化などに使える、 expect には Python 版があり、 その Windows 版もあるので共通に使える、 gnuplot プロンプトや出力を受けとって異なる処理ができる、 といった情報がよせられました。
また、ファイルの連結用のシステムコマンドについて、 Unix なら cat だが Windows なら copy を使えばいい、 システムコマンドをパイプ入力として、 「splot '<cat *.dat'」とすればいいが、 Windows で cat に対応するのは copy ではなく type である、 command.com の時代は con という標準入出力デバイスに 出力すれば標準出力に出せたが NT 系の cmd.exe には con はない、 正確には con は cmd.exe にないのではなく、 標準出力には出力できず con への出力が画面に固定されている、 だから「splot '<copy *.dat con'」のような使い方もだめ、 といった話がありました。 copy は標準出力に結果を出せませんので、 中間ファイルに一回書き出して、それを使うという方法になります。 なお、各データファイルに空行が入ってなければ空行を 1 行挟む必要がありますので、
echo.>nlineのように空行だけのファイル nline を作って それを挟んで連結すればいいわけです。この行は gnuplot スクリプト内に
copy data1+nline+data2+nline+data2 tmpf1
! echo.>nlineのように ! で書けば全部の作業を gnuplot スクリプトで行うことができます。 これを type で行えば中間ファイル tmpf1 は不要になります:
! copy data1+nline+data2+nline+data2 tmpf1
splot 'tmpf1' w pm3d
! echo.>nline
splot '<type data1 nline data2 nline data2' w pm3d
1 つの eps ファイルに複数のグラフを出力した際に
2 つ目のグラフの原点がずれてしまい、set origin でも解消しません、
という質問がありました。
(2850 の記事から始まるスレッド
「一つのepsファイルに複数のグラフを出力した際に
2つ目以降の原点がずれる現象の対処法を教えて下さい。」
2014 09/13: TAM さん)
元記事の方は、plot コマンドを別に 2 回発行していましたが、 松田さんからも回答がありましたが、 1 つのキャンバス (1 つのページ) に複数のグラフを書く場合は、 gnuplot では以下のいずれかを行うことになっています。
それに対して元記事の方は、「同一ファイル」内で「複数ページ」 のグラフを書きたいのだが、という話でした。
そして、eps から pdf に変換したら言われるように原点がずれる、 複数ページをサポートする pdfcairo terminal を使ったら、 「set te po eps」と EPS にしているようだが そもそも EPS には複数ページという概念がないので 複数ページの EPS を作るべきではない、 help post にもそう書いてあるからページ切り替えの際に 原点の初期化などが行われていなくても不思議ではない、 eps オプションをつけずに post 出力すれば複数ページの ps ができるのでは、 といった回答がありました。
これに関連して、 複数ページをサポートする pdf 出力をテストすると、 松田さんは「pdf terminal」でそれがうまくいく、 kakuto さんは「pdf terminal」ではだめで 「pdfcairo terminal」だとうまくいく、 という報告があったのですが、 「情報やメモ (2016 05/09)」 に書いたように、 「set term pdf」と指定しても実際には PDFlib 由来の pdf terminal ではなく pdfcairo terminal になっていて うまくいっている両者が pdfcairo である可能性が高いです。 実際、そのようだという報告もありました。
長方形グリッドでない 2 次元データを pm3d map で描画する際
set xrange で指定した境界がデータ点の間を通ると、
その外側の点が完全に無視されてしまう、
という質問がありました。
(2863 の記事から始まるスレッド
「pm3d mapでプロット外の点との間で補完したい」
2014 10/09: .gt. さん)
それに対して、set object polygon を使って、 クリッピングしたい領域を覆ってしまったらどうか、 という回答がありましたが、 元の質問者からやりたいことはその逆で グラフの余分な空白 (右側) を作りたくない、 それなら「set dgrid3d」のオプションを使用して 「set dgrid3d 2,100 spline」のように 細かいグリッドデータを作ったらどうか、 といった回答がありました。 質問者もそれで期待したものができた、 という返信がありました。
set label でラベルを置く位置を決めるのに
GUI でできるインターフェースはないか、
という質問がありました。
(2875 の記事から始まるスレッド
「GUI で label の位置決めをしたい」
2014 12/12: phys さん)
svg 出力を inkscaspe で調整したことはあるが、 svg 出力はフォントが崩れてしまう、 できれば eps か pdf で出したいが、 ということでした。
それに対して、ps, pdf の OSS のものはあまりいいものがない、 emf だと LibreOffice で編集できるのでは、 という回答がありましたが、 質問者の環境は Linux であるということでした。 そこで、wxt や x11 の対話環境の上で微調整する、 gv を eps の更新に合わせて 自動的に再描画するモードを利用し 調整しながら eps 画像を吐き出させる、 適切な位置を関数にして set label at で指定する、 Linux なら tgif terminal, xfig terimnal を使って tgif や xfig 上で (GUI で) 調整するという手もあるが、 tgif terminal や xfig terminal はあまり更新されていないので gnuplot の新しい機能には対応していないものがある、 グラフ付近にラベルを置きたい場合は with labels を使うとか、新しい gnuplot なら 「title columnheader at {beginning|end}」 を使うという手もある、 等の回答がありました。
結局元の質問者は、ケースバイケースで使い分けてみる、 ということでした。
gnuplot-4.6 で、
例えば「fsize = 12; set xlabel font ",fsize"」
としてもフォントサイズが適用されません、
という質問がありました。
(2884 の記事から始まるスレッド
「set xlabel font ",定義変数"」
2014 12/12: phys さん)
引用符の中で変数の値を使用する際、 perl などとは違い変数名を書いても、 確かにそういう文字列だとしか認識されません。
それに対して、変数値を指定したい場合は、 「fsize=",12"; set xlabel font @fsize」 としたらどうか、または 「fsize=12; set xlabel font ",".fsize」 や 「fsize=12; set xlabel font sprintf(",%d",fsize)」 とする手もある、という回答がありました。
変数値は引用符内では展開されませんので、 最初のマクロ展開を利用するやり方、 あるいは 2 番目の . 演算子で文字列として連結するやり方、 文字列値を返す書式文字列関数 sprintf() を利用するやり方などがあります。
ちなみに 2 番目の場合は、本来なら . が文字列結合演算子なので、 「fsize=12」よりも文字列として「fsize = "12"」 と定義すべきですが、gnuplot は . 演算子の際には 数値を文字列に自動的に変換してくれているようです。
個人的には、一番最後の方法が一番柔軟性は高そうな気はしますが、 ちょっと長いですかね。
(cf. 「情報やメモ (05/30 2016)」)
前回の報告 (02/10 2016)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。 ただし、4 月末位から大量の更新が入り、 その情報の整理がまだ追い付いていませんので、 一旦 04/27 までの分、としておきます。
今回の大きな変更は、以下のものでしょうか。
1. はまだ最近も改良、修正が続いていますから安定してないかもしれませんが、 set link で x2 軸を x 軸に非線形に割り付けることができていたのを、 set nonlinear で直接 x 軸 y 軸自体を非線形軸に 変更することができるようになりました。 対数軸のようなものを対数軸以外にも作れるようになったわけです。 例としてドキュメントには以下のようなものがあがっています。
set xrange [1:1000]
set nonlinear x via log10(x) inverse 10**x
set xrange [-3:3]
set nonlinear x via norm(x) inverse invnorm(x)
logit(p) = log(p/(1-p))
logistic(a) = 1. / (1. + exp(-a))
set xrange [.001 : .999]
set nonlinear y via logit(y) inverse logistic(y)
f(x) = (x <= 100) ? x : (x < 500) ? NaN : x-390
g(x) = (x <= 100) ? x : x+390
set xrange [0:1000] noextend
set nonlinear x via f(x) inverse g(x)
set xtics add (100,500)
2 つ目、3 つ目のサンプルはよくわかりませんが、 特定の分野で利用するもののようですね。 4 つ目は、データや関数の方の処理を工夫すれば 今までも近いことはできなくはなかったですが、 軸をそのようにできるのであれば、 関数やデータの処理は自然にできるので、こちらの方がいいと思います。
2. の pointtype, pointsize は、 従来は特定のデータを選択して複数のプロットを重ね書きすることで 同様のことを実現していたと思いますが、 この機能によりそういう作業がかなり楽になります。 例えば、以下のように、番号、性別 (男性 = 1、女性 = 2)、身長、 体重のデータがあるとします:
1 1 170 71このとき、横軸身長、縦軸体重の散布図を、 女性と男性とで別々の記号で with points でプロットするには、 従来は男性と女性のデータを別々に取り出して重ね書きするしか ありませんでした:
2 2 159 45
3 1 175 84
4 1 165 80
5 2 162 55
6 2 168 53
set pointsize 2
set grid
xd(x, v, n) = (v == n)? x : 1/0
plot for [j=1:2] 'data' using (xd($3, $2, j)):4 not w p pt j
上のサンプルでは xd() が、 v が n に等しくない場合は値を捨てる関数にしてあります。 同じことを、CVS 版では 1 つの plot でできるようになりました。
set pointsize 2
set grid
plot 'data' using 3:4:2:2 not w p lc variable pt variable
なお、lc variable も追加していますが、
pt variable だけだと記号は 2 列目の値で変わりますが色は同じものになります。
ただ、前者も良い点はあり、 前者だと記号毎に key (title) をつけられるのですが、 後者だと一つの plot になってしまうので、 記号毎の key (title) がつけられなくなってしまい、 別な方法で自作するしかなくなってしまいます。
「情報やメモ (05/03 2016)」 の gnuplot Q&A 掲示板 の質問記事のまとめの続きです。
CVS 版 gnuplot で線や点のデフォルトの「色列」が変更されているが、
なぜ紫が 1 番なのか、
これまでのスクリプトを変更して色を直接指定しないといけないか、
という質問がありました。
(2713 の記事から始まるスレッド
「『色列』の変更」
2014 04/09: 松岡さん)
この話は 「情報やメモ (04/01 2014)」 にも書きましたが、実は私もある時期 CVS 版を更新したら 次の日の日常的なログのグラフの色が変わったので、 グラフィックカードでも壊れたかと思いました。 従来の色列は「明赤、明緑、明青、明紫、明水色、明黄色、黒」 のようなもの (terminal によって違いがある) が多かったのですが、 今回デフォルトの色列が出力形式によって依存しないものに統一され、 しかもデフォルトの色列が従来のものとは違うものになっています (2014 03/22 より)。
質問にもあったように、デフォルトの 1 番は紫になっていますが、 その色列の変更の検討では 色弱者向けの色列に関する論文も調べられていますので、 多分デフォルトもそれに準じた考え方に基づいていると考えられます。 従来の列が単純に RGB から機械的に生成されたもの (古くから良く使われてきた RGB 8 色列) であったのに対し、 今回のものはより人間工学的な色列に変更されたと言えるでしょう。 この色列は version 5.0 からリリース版にも導入されていますが、 同時に set colorsequence というコマンドも導入され、 それでデフォルト列を変更することもできます (cf. 「情報やメモ (04/01 2014)」)。
よって、.gnuplot (MS-Windows の場合は GNUPLOT.INI) に 「set colorsequence classic」を入れておけば昔の挙動に戻ります。
ちなみに、現在のデフォルト列の RGB は、 #RRGGBB 24bit 形式で言うと、
#9400d3, #009e73, #56b4e9, #e69f00, #f0e442, #0072b2, #e51e10, #000000podo の場合は、
#000000, #e69f00, #56b4e9, #009e73, #f0e442, #0072b2, #d55e00, #cc79a7となっていて、 2 色以外は podo の列を並べ変えたものであることがわかります。
エラーバー付きでプロットで、誤差が相対的に小さい場合、
「工」の形のエラーバーが「+」のように上下の水平線が近づいて、
鉛直線がその水平線をつきぬけてしまう場合があり、
その場合つきぬけた「ひげ」の分誤差があるみたいに見えてしまう、
その「ひげ」を消す方法はないか、という質問がありました。
(2721 の記事から始まるスレッド
「エラーバーの『ひげ』を消す方法」
2014 05/09: 日向さん)
投稿記事にサンプルスクリプトがついていましたので、 その結果は以下のような画像になります (「plot 'data' with errorlines」)。 ただし、少しわかりやすくなるように、 「set pointsize 2; set bars 2」を追加してあります。
実は、この水平線をつきぬけている上下の「ひげ」は 誤差とは関係なく、「点」の記号の「+」(プラス) によるものです。 質問者は「with errorlines」でプロットしていたのですが、 「with errorlines」は「with points」「with lines」「誤差線」 の 3 要素 (または「with linespoints」「誤差線」の 2 要素とも言える) でできていて、 このグラフの誤差水平線の上下をつきぬけてしまっているのは、 その「with points」で表示されている「+」(pointtype 1) の記号の鉛直線です。 それは、pt 2 (pointtype 2) を追加指定 (「plot 'data' with errorlines pt 2」) するとよりはっきり確認できます。
だから、解決するには鉛直線のない pointtype を指定すればいいわけです。 例えば pt 0 (pointtype 0) とすれば点の部分が表示されなくなりますので、 鉛直線は全くなくなります (「plot 'data' with errorlines pt 0」)。
ただ、これだと「+」の場合に元々中心に書かれていた水平線 (「王」の真ん中の水平線) が消えてしまいます。 それを復活させるには、誤差 0 の水平誤差線を追加して書く、 という手があります。 必要ならば、その水平線の長さは set bars で調整できます。
plot 'data' with errorlines pt 0 lt 1,
'' using 1:2:(0) not with errorbars pt 0 lt 1
元記事の方は pt 0 で解決したそうですが、 実験の誤差線付きのグラフとしては point 部分の記号はむしろ「○」「●」「◆」 などが使われているものを良く見るような気がします。 それらは pt 6, pt7, pt 13 などを使えば実現できます。
MinGW でビルドした gnuplot のデフォルト
terminal はまず qt、次に wxt が優先されているようだが、
ソースのどの部分をいじればデフォルト terminal を変更できるのか、
という質問がありました。
(2781 の記事から始まるスレッド
「デフォルトターミナルの変更」
2014 05/30: 松岡さん)
質問者の松岡さんは、 CVS 版の MS-Windows 版のバイナリなどもビルドして公開しておられますが、 同じく MS-Windows 版のバイナリを公開している角藤さん版のものは GNUTERM 環境変数や GNUPLOT.INI を設定しなくても win terminal がデフォルトになっているようで、その角藤さんから、 config.h に C のマクロとして
#define DEFAULTTERM "wxt"
を定義する、
あるいはコンパイル時の Makefile でコンパイルコマンドラインに
「-DDEFAULTTERM=\"wxt\"
」がつくようにする、
といった方法で変更できる、と回答がありました。
DEFAULTTERM は、src/term.c というソースファイルで定義されていますが、 デフォルトでは指定がなければ NULL (何もなし) となっています。 確かに DEFAULTTERM を指定すると それがデフォルトの出力形式として使われるようですが、 せっかくですから gnuplot-5.0.3 の Windows の環境と X11 (Unix) の環境での デフォルトの出力形式の選択アルゴリズム (term.c の init_terminal()) を紹介しておきます。 まず、Windows の場合です。
初期設定ファイル (GNUPLOT.INI) での設定はこの 6. の後になりますので、 初期設定ファイルで定義すればそれがデフォルトになります。 なお、2. は 1. の設定の有無を見ていませんので、 2. があればそれは 1. を上書きします。
3. と 5. で 2 回 wxt の設定を行っているのは奇妙ですが、 ある種のバグとして残ってしまったもので、 実際 CVS 版では、3. は削除されています。 そのため、wxt, qt が有効で 1.,2. がない場合 (松岡さんの場合) は CVS 版では qt がデフォルトになってしまうわけです。 同じ状況で 5.0.3 では wxt がデフォルトになるはずです。
次は X11 環境 (Unix) の場合です。
初期設定ファイルでの設定はこの後です。 2. が 1. を上書きすることは Windows の場合と同じですが、 7. も 2. と同様 term が既に設定されているかを見ていないので、 7. がある場合は強制的に x11 になります。 また、Windows 同様、wxt, qt が有効で 1.,2. がない場合は やはりデフォルトは qt になります。 qt がなければ wxt がデフォルトになり、 x11 の優先度はその次になります。 こちらは Windows とは違い、 gnuplot-5.0.3 と CVS 版で違いはありません。
その他にも、VMS, NEXT, BeOS, OS2, MacOS など、 各プラットフォーム毎に 3. 以降のところで専用のデフォルトの terminal の設定が qt や wxt の設定の前、あるいは後ろに入っています。
このような状況なので、 デフォルトの出力形式を確実に固定したいのであれば、 角藤さんの回答通り 1. の DEFAULTTERM を指定してコンパイルするのが正しいと思います。
また、ついでに terminal 名に関する省略法についても 簡単に説明しておきます。 gnuplot では、「using」「with」「title」などを 「u」「w」「t」などのようにコマンドやオプション名の一部を省略できます。 これらは元々どこまで省略してよいかがそれぞれに決まっています。
一方、terminal 名の省略は少し違う仕組みになっていて、 指定した名前の terminal を有効な terminal 名一覧の中から探す際、 以下のようなルールによってそのマッチングを行うことにより、 名前の一部を省略することが可能なようになっています。 よって、省略名のルールは有効な temrinal の一覧に依存し、 どのような temrinal が有効かによって 省略名と terminal の対応が変わる仕様になっています。
例えば、libgd 系の png terminal と pngcairo terminal が有効な状態で「set term png」とすれば上のルール 1. により libgd 系の png terminal が選択され、 「set term pn」とすればルール 3. により unknown になります。 そして、libgd 系の png terminal が有効ではなく (libgd なしで gnuplot がコンパイルされている)、 pngcairo terminal のみが有効な場合に「set term png」 あるいは「set term pn」とすれば、 上のルール 2. により pngcairo terminal が選択されることになります。 pdf についても、古い PDFlib 系の pdf terminal と cairo 系の pdfcairo terminal がありますが、 状況は png と同じです。
ただし、現在の 5.0.3, および CVS 版では以下の 2 つだけ 例外が設けられています。
この後者は、post terminal の eps オプションとは関係なく、 むしろ epslatex terminal への対処だと思われます。 cairo 系が有効な場合、通常なら「set term eps」は、 epslatex と epscairo があるためルール 3. により unknown になるはずです。 しかし、上記の例外ルールにより「eps」(か 「ep」か「e」) なら「epscairo」とし、 epslatex terminal にしたければ「epslatex」(最低「epsl」) とせよ、 ということになっています。 個人的には eps に関して例外にする必要性を感じないのですが、 この辺りは開発者の思い入れが伺えますね。
「s(t)=I(t)*cos(2π*1000*t) + Q(t)*sin(2π*1000*t)」
のような関数を表示させたいのですが可能でしょうか、
という質問がありました。
条件として「πは 3.1415、t は整数、I(t), Q(t) は小数も取りうる」
とありました。
(2792 の記事から始まるスレッド
「このようなs(t)と言う関数は表示できますか」
2014 06/12: イッシューさん)
どういう問題なのかがややよくわからず、 条件として書かれていることの意味もわからないところもありますが、 I(t), Q(t) が既知の関数で、 それに対して上の s(t) という関数の t が「整数」の場合の値のみをグラフに表したい、 ということなら一応可能です。
gnuplot の関数のグラフは、標本点の値を求め、 それを折れ線で結んだり、その場所に点を書いたりしているだけなので、 標本点を整数だけに限ればいいわけです。 例えば以下のようにします。
f(x) = x**2 + 1
set xrange [0:10]
set samples 11
plot f(x) with boxes
このように x の範囲を 0 から 10 にして、標本点数を 11 にすれば、
等間隔の 11 点である 0 から 10 までの整数値を標本点にしてくれます。
もし、xrange の範囲は [-0.5:10.2] にして、 1 から 8 までの整数値を標本点にしたい、 という場合は、少し面倒ですが以下のような手が考えられます。
前者は例えば以下のようにします。
f(x) = x**2 + 1
xv(x) = (x < 1 || x >= 9) ? 1/0 : floor(x)
set xrange [-0.5:10.2]
set boxwidth 1
plot '+' using (xv($1)):(f(xv($1))) with boxes
xv(x) で 1 未満の値と 9 以上の値を捨てていて、
1 以上 9 未満の値に対してその整数部分を利用してグラフを書きます。
set boxwidth は自動設定されないように指定しています。
また、後者の parametric を用いる方法は以下のようになります。
f(x) = x**2+1
set xrange [-0.5:10.2]
set parametric
set trange [1:8]
set samples 8
plot t, f(t) w boxes
こちらの方がだいぶ自然ですが、parametric にしているため、
他のグラフと重ねる必要があるとむしろ面倒かもしれません。
なお、掲示板では元記事の方の反応がなかったので、 結局疑問点は解消されないままでしたが、πが円周率で t が整数なら 実際には「s(t) = I(t)」となるはずなので、 多分問題の正しく伝わっていない部分があったのではないかと思います。
(cf. 「情報やメモ (05/17 2016)」)
「情報やメモ (03/30 2016)」 の gnuplot Q&A 掲示板 の質問記事のまとめの続きです。
gnuplot-4.6.4 の emf terminal で、
塗り潰し (filled) 矢印と pt 6 (白抜きの丸) に対する
lw 指定がが反映されないのだが、という質問がありました。
pt 6 の方は 2ch から拾ったネタだそうです。
(2673 の記事から始まるスレッド
「emfターミナルの一部で線幅が反映されない。」
2013 11/18: ryo-naka さん)
これは、linewidth に関するバグだったので、 本家のサイトに報告し修正されましたが、 引き続き、multiplot を行うと、 2 度目の plot のタイトル文字列等がおかしくなる、 という報告もありました。これも 2ch の記事からのようですが、 やはり font の初期化に関するバグを見つけましたので、 報告し修正されました。 詳しくは、既に 「情報やメモ (11/28 2013)」 に書いてあります。
で、そこにも書いてありますが、 さらに 2ch の記事にあった emf terminal のパターン fill も、 win terminal のビットパターンの実装を拝借して、 他の terminal と同系統のパターン fill になるように やっつけ仕事で作ってみたものを本家に送ったら、 めでたく採用されました。 ただし LibreOffice でうまく表示されないなど、 完全ではないようです。それは LibreOffice 側の問題かもしれせん。 詳しくは、既に 「情報やメモ (12/27 2013)」 「情報やメモ (07/22 2014)」 に書いてあります。 さらにその後も引き続き、fill pattern の実装の確認や、 他のソフトでの実装の状況、 Win32 API が提供する標準的なパターンと gnuplot の標準パターンとの関係に関する議論が多少続きました。
現状、パターン fill の性能としては Win32 API が提供するパターンを利用するのが良いのですが、 それだと gnuplot の他の terminal と同様のパターンが実現できません。 逆に gnuplot 標準のパターンを実装するとビットマップパターンなので、 その EMF を使う場面であまり綺麗でなくなる、という問題があります。 その辺りを切り替えるオプションでも作ればいいのかもしれませんが、 とりあえず現在は gnuplot 標準を重視した形になっています。 時間があったらオプションについても考えてみたいと思います。
n=08 や n=09 とすると「unexpected or unrecognized token」
などというエラーが出るのだが、という質問がありました。
(2686 の記事から始まるスレッド
「n=08 がエラー?」
2014-02-14: a user さん)
これは、数値を扱う環境ではありがちなのですが、 「0 から始まる数値は 8 進数とみなす」 「0x から始まる数値は 16 進数とみなす」 という C 言語の流儀に習った数値の処理が gnuplot でも行われているための問題です。 よって、「08」は 0 から始まっているので 8 進数であるはずなのに、 8 進数ではありえない「8」が次に使われているので、 認識できない、ということになっているわけです。
それは C のライブラリ関数を使用して 読み込んだ数値の認識をやっているからなのですが、 それは atoi() を使っているから、 atoi() だと基数の変換はやらないので strtol() である、 といった議論に発展しました。
なお、0x や 0 から始まる数値の話は この頃はヘルプには書かれていなかったのですが、 そのしばらく後 (04/02 2015) にドキュメントに追加されました (by Karl Ratzsch さん)。
(cf. 「情報やメモ (05/09 2016)」)
「情報やメモ (03/24 2016)」 の gnuplot Q&A 掲示板 のまとめの続きです。
gnuplot 4.7 (角藤版 wgnuplot) を使っているが、
新しく導入されたブロック形式の if から reread が実行できない、
これは仕様なのか、という質問がありました。
(2640 の記事から始まるスレッド
「ブロックifからrereadできない?」
2013 04/05: あま蔵 さん)
確かに、gnuplot-4.6 で新しく導入された while/do/if/else などの { } で囲むブロックを用いる構文は、 古いかっこのない if/else 構文、reread とは共存できません。 実際 if のブロック { } の中に reread を書いても無視されます。
ただ、ブロックの外であれば、 従来の「if (条件) reread」の一行 if の文を書くことは可能なので、 そういう方法を使うことはできます。
現在はループの構成に while/do/if/else 等が使えるので、 古い reread を使う必要はだいぶなくなってきました。 それに、元記事の方もそうだったようですが、「reread」という名前が、 そのコマンドが行う動作に誤解を与える場合もありますし、 使わないでよければ使わない方がスクリプトは わかりやすくなるのではないかと思います。
元記事の方がやりたかったのは、 gnuplot でグラフを作り、それを画面で確認し、 pause でそれを画像ファイルにするかを選択して、 その後パラメータを変更してまたグラフを作る作業に戻る、 といったループのようでした。 それなら reread を使うよりも while/do などで作業を行う方が自然だと思います。
例えば、f(x) = sin nx のグラフを、n = 1 から 10 まで、 sin-01.gif のような名前で保存するようなスクリプトを考えてみます。 画面で確認して、不要ならば画像ファイルにはしない、 という処理も入れることにします。 その対話型処理には、「pause mouse」を使用します。 gnuplot-4.6 以上で動作します。
reset
set xrange [-1:7]
set yrange [-1.2:1.2]
set grid
do for [n=1:3] {
set title sprintf("y = sin %d x", n)
plot sin(n*x) not
pause mouse keypress "Save gif file ? (y/n)\n"
if (MOUSE_CHAR ne 'n') {
set term push
set term gif
set output
sprintf("sin-%02d.gif", n)
replot
unset output
set term pop
}
}
コマンドウィンドウ上に「Save gif file ? (y/n)」という表示が出ますが、
グラフウィンドウの上で y か n のキーを押すと pause が解除されます。
ただし Windows 版 gnuplot の場合、
バージョンや GUI 版 (wgnuplot.exe) か CUI 版 (gnuplot.exe)
によってメッセージの表示や動作が不安定である可能性があります
(うちでは 4.7 では CUI 版だとコマンドウィンドウをクリックして
グラフウィンドウに戻らないといけなかったり、
5.0.3 だと GUI 版、CUI 版ともにメッセージが表示されなかったりしている)。
terminal を画面描画に戻すには「set term win」(または「set term x11」等) としてもいいのですが、現在は「set term {push | pop}」 という機能があり、このような目的のために利用できます。
新しい構文を使わずに、古い if reread によるループで書くと こんな感じでしょうか:
reset
set xrange [-1:7]
set yrange [-1.2:1.2]
set grid
if (!exist("loop")) loop = 1 ; else loop = loop + 1
set title sprintf("y = sin %d x", loop)
plot sin(loop*x) not
pause mouse keypress "Save gif file ? (y/n)\n"
if (MOUSE_CHAR eq 'n' && loop >= 10) quit ;
else if (MOUSE_CHAR eq 'n') reread
set term push
set term gif
set output sprintf("sin-%02d.gif", loop)
replot
unset output
set term pop
if (loop < 10) reread
なお、現在対話的にキー入力を受け取ってスクリプトの動作を変える方法は、
pause mouse を利用するくらいしかなく、
キーの一文字、あるいはマウスボタンの情報などの値しか受け取れません。
文字列を入力して対話的にスクリプトで使用したい、
という場面もありそうな気もしますので、
暇なときにでも考えてみたいと思います。
gnuplot-4.6.3 で emf terminal で test コマンドを実行したら、
そこの文字が一部分小さく潰れてしまった、
という報告がありました。
4.6.0 では発生せず、4.6.1 以降で発生する、
test コマンドだけで起こっているようだ、とのことでした。
(2653 の記事から始まるスレッド
「emfターミナルのtestコマンド結果」
2013 04/25: ryo-naka さん)
実は、その辺りの emf terminal の修正に関わっていたので、 それが問題かなと調べてみたら、 emf terminal のフォントの初期化に問題があったようです。 gnuplot-4.6.4 以降では修正されています。
Solaris 11.1 で gnuplot 4.6.3 をコンパイルして wxt terminal
で実行しようとすると libpng に関するエラーがでる、
という質問がありました。
(2656 の記事から始まるスレッド
「Gnuplot 4.6.3 on Solaris における libpng のエラーについて」
2013 05/10: Shimmura さん)
具体的には、以下のようなメッセージが出るそうです:
Application was compiled with png.h from libpng-1.2.49使用している libpng のライブラリとヘッダのバージョンが 合っていないようなメッセージですが、 現在の gnuplot は以下のようないくつかの場面で libpng を引いているので、 注意が必要です。
Application is running with png.c from libpng-1.4.11
Incompatible libpng version in application and library
Couldn't load a PNG image - file is corrupted or not enough memory
libpng は良く更新されていて、 複数のバージョンの libpng があちこちにある、 という環境もあるかと思います。 そうなると、上のようなライブラリの make 時にそれらが参照する libpng のバージョンが異なってしまうことがありえます。
元記事の方は結果的にホームディレクトリで wxGTK を新たに make し直して、 CFLAGS, CXXFLAGS, CPPFLAGS, CAIROEPS_CFLAGS, LDFLAGS などに libpng がある場所とその wxGTK のある場所を指定して configure してやったらうまくできたそうです。 私も gtk 関係や wxGTK を自前でコンパイルしていますが、 新しい gtk, 新しい wxGTK を make するときは、 「全部 /usr/local/* に入れて前のものに上書きする」という形式ではなく、 引いたりするライブラリが混在しないように 新たに専用のディレクトリを作って、 その中にヘッダファイルやライブラリを なるべく閉じた形で入れるようにしていますし、 gnuplot のコンパイル時には上記のような環境変数の設定も (上記以外にも PKG_CONFIG_PATH も) 行いますし、 make 時のオプション指定、configure の書き換えなどを行うこともあります。
この問題は、主に「共有ライブラリ」による問題だと思いますが、 共有ライブラリはある意味では便利な考え方なのですが、 ライブラリを更新したい場合には色々不便なこともあり、 結局静的なライブラリの方が管理が楽だなと思うこともあります。
(cf. 「情報やメモ (05/03 2016)」)
「情報やメモ (03/24 2016)」 に書いた 3 角 gnuplot Q&A 掲示版 2635 番の記事 「3角メッシュの 3d plot」 に対する話の続きです。
元記事の方のデータがどういうものかよくわからなかったので、 「情報やメモ (03/24 2016)」 で示した data0 のように単純に点のデータが並んだものから 3 つずつの並びを順に取りだしたもの、と仮定した話を書きましたが、 それだと任意の 3 角メッシュを作ることはできないので、 多分元の方のデータはこうではないと思います。
3 角メッシュというと通常有限要素法のデータが思い浮かぶと思いますが、 例えば FreeFem++ (http://www.freefem.org) というフリーの有限要素法計算ソフトの場合で少しその話を考えてみます。 まず参考資料をいくつか上げます。
例えば上の 1., 2. の「おまけ: gnuplot で可視化」の節、 3. の「gnuplot による可視化」の節に見られるように、 FreeFem++ では三角形の各頂点のデータを配列データとして持っていて、 それらでは gnuplot 用にその配列データを 「情報やメモ (03/24 2016)」 の data2 の形式、すなわち各三角形毎の index データ (2 行空行区切り) として、 三角形が閉ループになるような 4 点のデータにして出力しています。 ただし、このデータでは with lines でないと表示できません。
この FreeFem++ の環境を仮定すれば、 以下のように 「情報やメモ (03/24 2016)」 の data3 に近い形、すなわち、
x11 y11 z11 c1で出力させることは容易で、その出力を用いれば with pm3d で各三角形を色付けして表示させることが可能です。 なお、4 列目の ci の値は、zi1, zi2, zi3 の平均値です。
x12 y12 z12 c1
(空行)
x13 y13 z13 c1
x12 y12 z12 c1
(空行)
(空行)
x21 y21 z21 c2
x22 y22 z22 c2
(空行)
x23 y23 z23 c2
x22 y22 z22 c2
(空行)
(空行)
.....
上を少し説明します。上の形式のデータでは、 各 index データにブロックが 2 つずつあり、 各ブロックには 2 点ずつがある構造になっていて、 つまりブロックの点数が等しい grid (格子状) データという構造になっています。 gnuplot は grid データの曲面描画では、 with lines ではその格子に合わせて縦横の線 (ブロック内の線とブロック間の線) を引き、with pm3d では格子を構成する四角形単位で色を塗ります (色はデフォルトでは 4 点の z 座標の平均値)。
よって、上のようなデータ、すなわち 1 つ目のブロックが A=P1, B=P2 の 2 点、 2 つ目のブロックが C=P3, D=P2 の 2 点のようなデータの場合、 gnuplot は with pm3d では四角形「ABDC」を塗ろうとしますが、 それは P1-P2-P2-P3 なので、実際には三角形 ABC (P1-P2-P3) が塗られることになるわけです。 デフォルトではその色は、P1, P2, P2, P3 の 4 点の z 座標の平均値となってしまい、P2 のウェイトが高くなってしまいますが、 その代わりに 4 点すべての 4 列目に P1, P2, P3 の z 座標の平均値 (ci) の同じ値を置いて using で追加指定することで、 その値での色付けができるようになります。
上記サイト 1., 2. の「おまけ: gnuplot で可視化」の節では、 FreeFem++ で、
{
ofstream ug("u-g.txt");
for (int i=0; i<Th.nt; i++) {
for (int j=0; j<3; j++) {
ug
<< Th[i][j].x << " "
<< Th[i][j].y << " "
<< u[][Vh(i,j)] << endl;
}
ug
<< Th[i][0].x << " "
<< Th[i][0].y << " "
<< u[][Vh(i,0)] << "\n\n\n";
}
}
として data2 形式のデータ u-g.txt を出力していますが、
FreeFem++ ではその下に以下を追加すれば、
上で説明した pm3d 用のデータ u-g2.txt も出力できます:
{
ofstream ug2("u-g2.txt");
real m;
for (int i=0; i<Th.nt; i++) {
m =
(u[][Vh(i,0)] + u[][Vh(i,1)] + u[][Vh(i,2)])/3.0;
ug2
<< Th[i][0].x << " "
<< Th[i][0].y << " "
<< u[][Vh(i,0)] << " "
<< m << endl;
ug2
<< Th[i][1].x << " "
<< Th[i][1].y << " "
<< u[][Vh(i,1)] << " "
<< m << endl;
ug2 << endl;
ug2
<< Th[i][2].x << " "
<< Th[i][2].y << " "
<< u[][Vh(i,2)] << " "
<< m << endl;
ug2
<< Th[i][1].x << " "
<< Th[i][1].y << " "
<< u[][Vh(i,1)] << " "
<< m << endl;
ug2 << endl << endl;
}
それらの出力を gnuplot で、
splot 'u-g2.txt' using 1:2:3:4 with pm3d,
'u-g.txt' using 1:2:3 with lines lt -1
で描画してやれば、with pm3d で三角形に色付けできます
(各三角形の with lines での境界描画も追加している):
これでようやく gnuplot Q&A 掲示版 の 2639 番の返答よりは 多少はましな回答になるのではないかと思います。
「情報やメモ (03/23 2016)」 に書いた gnuplot Q&A 掲示板 のまとめの続きです。 今度は、質問記事等を順番にまとめていきます。
wgnuplot での日本語入力時に、 従来 (2011 3 月頃まで) は直接日本語が表示されず、 他のウィンドウで一回隠したりすると正しく表示される、 という状況になっていたが、 2011 10 月頃にはそれが解消されている、 それはいつ頃解消されたのか、という質問がありました (私がしました)。
結局回答はありませんでしたが、ChangeLog を見ると、 2011-03-28 あたりの修正がもしかしたらそれかもしれません。 その後も、wgnuplot は GDI+ による大幅な書き換えとかも行われていたので、 それらいずれかの段階で解消されたのでしょう。
(2569 の記事 「wgnuplotの日本語入力」 2011 11/11: 竹の)
「set ylabel "{/Symbol x}^{/Symbol \136}_{CG}/L"」 とすると「enhanced text parser - spurious }」というエラーが出る、 '\136' が問題のようだが '\244' や '\141' とすると問題ない、という質問がありました。
これは、実は quoting (help quote) の問題で、 2 重引用符 (") で囲んでいるために起きる問題です。 2 重引用符内では \136 は '^' に展開されますが、 '^' は enhanced mode の制御文字 (上付き) で、 その次になんらかの文字が来なければいけないのに、} が来てしまった、 というエラーを出しているわけです。
その展開を防ぐには、1 重引用符 (') で囲むか、 \136 を \\136 にする必要があります。
(2579 の記事から始まるスレッド 「文字コードを直接入力する。」 2012 01/12: sin-nishi さん)
MS-Windows 用の wgnuplot.exe と gnuplot.exe (コンソール版) で、 -p (persist) オプションの違いについて質問がありました (私がしました)。 「wgnuplot -p script.gp」「gnuplot -p script.gp」のいずれも グラフウィンドウが残るところは同じだけど、 wgnuplot.exe は元のコマンドプロンプトに戻るけど、 gnuplot.exe の方は gnuplot プロンプトに戻って gnuplot が終了しないようだが、という質問です。
松岡さんがテストや変更履歴を調べてくださって、 Windows には fork() がないから、という話になりました。 現在もこの仕様はあまり変わっていないようで、 gnuplot.exe の方は -p の場合は、 現在は gnuplot プロンプトは表示されないのですが、 グラフウィンドウを閉じないとコマンドプロンプトが使えない状態になります。 wgnuplot.exe の方は グラフウィンドウが立ち上がったままでコマンドプロンプトが使えます。 とすると、意外にもバッチファイルなどで -p を使う場合は、 gnuplot.exe よりも wgnuplot.exe を使う方がいい場面などもありそうです。
(2590 の記事から始まるスレッド 「Win32 の gnuplot の -p」 2012 02/10: 竹の)
gnuplot-4.6 で作成した emf ファイル (emf terminal) を挿入した MS-Word (2007) の文書を PDF 形式で保存しようとすると 「原因不明のエラーが発生した」というエラーがでて PDF ファイルが作成できない、 という質問がありました。
議論やテストの結果、以下のようなことがわかりました。
emf terminal のソースや吐き出される EMF ファイルを調べたのですが、 with point の際の EMF 描画命令のリセットが 抜けているとそのような問題が起きるようでした。 四角が余計に表示されるのは、 2 度境界が書かれていてその描画命令が EMF 命令の最後になっているとずれてしまうようで、 無意味な命令を最後に追加したら問題は解消しました。
いずれも、EMF 的にはあまり問題なさそうで、 実際に MS-Word に貼りつけるだけだと問題ないのに、 PDF に変換する際に問題になっているので、 gnuplot が生成する EMF ファイルの問題というよりも、 むしろ MS-Word が PDF に変換する部分に問題があるような気もします。 とりあえず、現在の CVS 版や gnuplot 5.0 では、 emf terminal に上記のような回避策が採用されています。
(2604 の記事から始まるスレッド emfを含むMS-Word文書をPDFにエクスポートできない 2012 08/22: ryo-naka さん)
emf terminal の出力で、凡例 (key) のタイトルと線と点が一直線に並ばず、 タイトルが線や点よりも下に出力されてしまう、 set key にはそれらを調整するようなオプションがない、 gnuplot の 4.0 から 4.2.3 までは問題はなかったが、 4.6 でうまくいく方法はないか、 という質問がありました。
実は gnuplot の新しいものでは key のフォントを 独立に指定できるようになっているため、 それで上下にずれたようになっていたようです。 また、元記事の方は正しくないフォント名を指定したり、 古いフォント指定と新しいフォント指定も混在していました。 「set key font 'Arial,12'」のように emf terminal のデフォルトフォントを key に指定すれば 多分問題は解消したと思います。
なお、win terminal の「EMF 出力」では問題は起こらず、 また現在の emf terminal ではその問題も修正されています。 ただし、key の微調整 (title と sample の位置関係) ができるようなオプションはあると便利かもしれません。
(2619 の記事から始まるスレッド 「凡例でタイトルと線やポイントが一直線に表示されない」 2012 12/25: yokoyama さん)
Mac OSX 10.7.5 (Lion) で gnuplot-4.6.1 の make がうまくいきません、 という質問がありました。
先に freetype-2.4.11, gd-2.0.28 をインストールしたとあったのですが、 そこで出ている term/gd.trm のエラーメッセージ 「error: 'gdDisposalRestorePrevious' undeclared」 が gd-2.0.28 にはないものでした。 gd-2.0.35 だとこれは出なくなります。
しかし今度は、インストールした gnuplot を実行し aqua terminal で plot しようとすると「Abort trap: 6」 というエラーで止まる、という話でした。 検索すると、以下のようなサイトが見つかりました。
readline 以外は割と標準的なことしか書いてないようですが、 元記事の方は結局一回 freetype と gnuplot のフォルダをさらにして インストールし直したらうまくいった、とありました。 上のサイトで指摘されている readline は、gnuplot builtin のもの (--with-readline=builtin) を使っているようです。
(2629 の記事から始まるスレッド 「gnuplot-4.6.1 で make できない」 2013 03/06: nochino さん)
3 角メッシュ上のデータ (3 次元データ) を pm3d で 3 次元描画したり、 contour 描画したいのですが、という質問がありました。 set pm3d で set dgrid3d したのだけど、不自然になる、 という話でした。 データは、3 角メッシュの各頂点とその点での z 値である (x, y, z) の組がただ並んでいるだけのようです。
gnuplot は元々「3 角メッシュ」なる形状の描画には慣れていません。 dgrid3d は、格子状でないデータから 無理矢理格子状のデータを作成するオプションなので、 データによってはどうしても不自然な状態になってしまいます。
「3 角メッシュ」のデータがよくわからないのですが、 例えば、各列が x, y, z, N (N は説明用の点名) だとすれば、
0 0 5 Aというデータ (data0) が 2 つの 3 次元空間の三角形の頂点、 すなわち三角形 ABC と三角形 BCD というものを表わしていて、 その 3 次元空間内の三角形を描画したいのであれば、 このデータを
2 0 8 B
1 2 7 C
3 1 2 D
0 0 5 Aという三角形毎のデータ (data1) に直すことができれば splot できるのでは、とそのときは書いたのですが (2639 の記事)、 良く考えてみると、実は gnuplot ではかなり難しいことがわかりました。
2 0 8 B
1 2 7 C
2 0 8 B
1 2 7 C
3 1 2 D
まず、上のように 3 点ずつに分離した場合、 「三角形」とは認識されません。 「三角形」と認識させるには、出発点を追加した
0 0 5 Aのようなデータ (data2) でないとだめでしょう。
2 0 8 B
1 2 7 C
0 0 5 A
2 0 8 B
1 2 7 C
3 1 2 D
2 0 8 B
これで「splot 'data2' using 1:2:3 with lines」 で三角形が書けそうですが、そこにも問題があります。 上のデータは、各データブロックの点の数が同じ格子状データ (grid data) になっているので、splot をするとブロック内の点が線で結ばれる (A-B-C、B-C-D) だけでなく、 ブロック間の対応する点も線で結ばれてしまいます (A-B, B-C, C-D)。
上の並びの場合は問題ないのですが、 2 つ目のブロックの点を B, C, D, B の順でなく、 例えば D, B, C, D の順のループにしたりすると余計な線分 AD を結ぶ線が書かれてしまうことになります。 現在の splot では、x-孤立線と y-孤立線の一方だけを 書かないようにすることができません。
これを避けるためには、data2 の並びにするか、 空行を 2 行に増やすという手がありますが、 2 行の空行にしてしまうと、 gnuplot 的にはデータが「曲面」を構成しないことになるので、 今度は with pm3d での表示ができなくなります。
data2 の場合、with pm3d の色付けは、 格子状データの格子四角形に対して行われますので、 次の 3 つの四角形に対して色付けされることになります:
しかも、四角形 1 は、四角形になるように「A→B→C→B→A」 の順の閉ループとみなされるので、残念ながら三角形 ABC にはなりません。 四角形 2 も同様です。 四角形 3 は、「C→A→B→D→C」の四角形なので、 4 点全体からなる四角形 ABDC (= 三角形 ABC と三角形 BCD を合わせたもの) となり、結局この四角形 3 の塗り潰しで全体が同じ色 (A,B,C,D の z の平均値) で塗られてしまうことになります。
本来は、三角形 ABC と三角形 BCD が、 それぞれ頂点の z 座標の平均値で三角形が塗られないといけないのですが、 そうはなりません。data1 を使えば四角形 3 はありませんが、 四角形 1、四角形 2 がそれぞれ三角形にならないので何も表示されません。 四角形 1, 2 が三角形とみなされるためには、 data1 の 2 つ目のデータブロックの順番を入れかえて
0 0 5 Aとしないといけないのですが (data3)、 このような入れ替えは、 もう 1 点 (E) を増やした 3 つの三角形の場合には破綻します。 また、z 値も 4 点の平均値になっていて、 一つの点だけ weight が大きいことになってしまいます。
2 0 8 B
1 2 7 C
1 2 7 C
2 0 8 B
3 1 2 D
つまり、3 次元の「3 角メッシュ」の描画は易しくはないようです。
なお元記事の方は、各三角形毎に線形補間したデータを作成して それを splot すればいけそうだ、という話のようでした。
(2635 の記事から始まるスレッド 「3角メッシュの 3d plot」 2013 03/21: pais さん)
「情報やメモ (10/11 2011)」 以降、ずいぶん長いこと gnuplot Q&A 掲示板 のまとめの備忘録のようなことをやっていませんでしたが、 せっかくですから簡単にそれ以後の話をまとめておきます。
まずは、追加機能やリリース情報等の各種アナウンスの記事 (スレッドになっていても、実質ほぼアナウンスだけのもの) を以下に上げます。 左の番号は、掲示板の記事番号、 右のカッコ内は最初の記事の投稿日と投稿者です。
次は、追加機能やリリース情報等の各種アナウンスの記事から派生した スレッドを以下に上げます。 左の番号は、掲示板の記事番号、 右のカッコ内は最初の記事の投稿日と投稿者です。
実際に松岡さんと松田さんが import 機能のテストを行った話の スレッドがついています。
terminal のヘルプに関するスレッドがついています。
Windows 版バイナリの作成に関するスレッドがついています。
win terminal での EMF 出力のバグの話なども出ましたが、 kakuto さんと松岡さんが連絡しあって、 wxt terminal, cairo 系 terminal qt terminal のバイナリのビルドの問題や、 その動作を検証する長いスレッドがつきました。
これも、2ch の記事の内容の話に派生して、 Qt のバイナリの動作の問題を修正するための議論になりました。
一つ、MS-Windows で前のものが残った状態で gnuplot-5.0.1 をインストールすると問題が起きることがスレッドで報告されています。
この件に対応する MD5 の checksum の話、 および SourceForge 等の運営に関する意見などがスレッドにつきました。
SourceForge が落ちたという話でしたが、 CVS ツリーがバックアップされている github サイトの紹介などがスレッドにつきました。
スレッドではさっそく松田さんがすごいサンプルを作ったものが紹介され、 さらに立体視の 3D グラフの話になりました。
さっそく 5.0.2 の wxt terminal にフォント指定に関するバグが見つかり、 そのため予定になかった 5.0.3 がリリースされる、 という話がスレッドで紹介されました。
これは、通常 key に表示される各グラフのタイトルの位置を 自由な場所に変更できるオプションですが、 スレッドではそれに関連してグラフタイトルの回転、 win terminal や post terminal での ylabel の回転の話になりました。
win, post の terminal では、 win の場合は例えば @MSMincho.ttc、 post の場合は例えば Ryumin-Light-EUC-V のように、 縦書き用のフォントを指定すると ylabel を縦書きにできなくはないのですが、 元々 gnuplot が縦書きを想定しておらず、 ある意味で無理矢理な実行であるため 単に指定しただけでは正しい方向にでてくれません。
win terminal の場合、
set term win
set encoding sjis
set ylabel &quopt;日本語&quptl font "@MSMincho.ttc"
だと逆立ちしてしまい、
set term win
set encoding sjis
set ylabel &quopt;日本語&quptl font "@MSMincho.ttc"
rotate by 270
とする必要があります。
一方 post terminal では (Unix での場合)、
set term post
set ylabel &quopt;日本語&quptl font "Ryumin-Light-EUC-V"
だと横向きにでてしまい、
set term post
set ylabel &quopt;日本語&quptl font "Ryumin-Light-EUC-V"
rotate by 0
のようにする必要があります。
回転指定に統一性がないのは、
gnuplot で縦書きフォントに対する処理が考慮されていないためでしょう。
新たに CVS 版で配列変数がサポートされたという話ですが、 早速ファイルの中にあるデータを配列に保存するには、 という質問があり、stat を使う例が 2 つ紹介されました。
一つは、ファイルの列データ (例えば 2 列目) を配列に保存する方法です。
stats 'data' noout
array col2[STATS_records]
i = 0
stats 'data' using (i=i+1, col2[i]=$2) noout
2 回 stat を使っていますが、1 回目の stat でデータの行数を取得、
それで配列を宣言して、
2 回目の stat で i とカンマ演算子を使って
各行の値を配列に保存しています。
なお、この最後の行は、$0 (= 行数 - 1) を使って、i なしで単に
stats 'data' using (col2[int($0 + 1)]=$2) noout
とすることも可能です。
もう一つは、ファイルの行データ (例えば 1 行目) を配列に保存する方法です。 これは do for と組み合わせれば可能ですが、 何列あるかを stat 等であらかじめ知ることはできません。
array row1[10]
do for [i=1:10] {
stats 'data' using (s[i]=$i) every ::0::0 noout
}
every は、1 行目だけを見るためにつけています。
後の残りが質問記事なのですが、だいぶ長くなったので とりあえず今回はここまでとして、 質問記事の方はまた後日順番にまとめていきたいと思います。
(cf. 「情報やメモ (03/24 2016)」)
先日 (02/21) gnuplot-5.0.3 がリリースされました。 gnuplot-5.0.2 が出たばかりでしたが、 wxt のフォント周りに大きな問題があったので、 緊急にパッチが作られ、ついでにいくつかの terminal の修正が入っています。 5.0.3 での新規機能、変更、修正は以下のようです。
今回は上記の事情で更新点は少ないのですが、 plot for の終りの定数を指定しなくてすむ仕様、 および tkcanvas の大幅な改訂はそれなりに新しい機能です。 日本語マニュアル も更新しておきました。
(cf. 「情報やメモ (2016 07/29)」)
少し間が開きましたが、 前回の報告 (11/02 2015)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
さすがに 3 ヶ月ほど開いたので、 たくさんの変更、修正などが行われていますが、 主なものを紹介します。
3. は、従来 word(string, -1) は文字列の長さを返していたようですが (内部仕様)、それはユーザに取ってはバグになりかねないので、 現在は期待通りに "" を返すように修正されています。
4. は、pm3d で単純な光源モデルをサポートしたものです。 サンプルは以下にあります。
こういうグラフを自前で作っておられた方もいたようですが、 多少はそういうことが楽になるのではないかと思います。 特に、さっそく作られた松田@東京電機大 さんの例は、 とても gnuplot で書いたとは思えません。
5. は、「set linetype cycle N」と同様、 白黒のグラフで線種のサイクルを指定数に限定するものです。
6. は、system() を利用するスクリプトでは重宝するかもしれません。
7. は、通常 key としてまとめて表示される各グラフの凡例を、 グラフ内の任意の位置に置くための指定です。 これにより、例えば multiplot で複数書いたグラフの key を 1 つにまとめたりすることができます。 サンプルは以下にあります。
8. は、通常 gnuplot の help コマンドで、 調べたいコマンド、キーワード名全部でなくて短い名前を打った場合は、
gnuplot> help xt Ambiguous request 'xt'; possible matches: xterm xticlabels xticsのように、その候補となるもの一覧を表示する機能があるのですが、なぜか
gnuplot> help lo Ambiguous request 'lo'; possible matches: load locale log lowerとなって、「logscale」が出てこない問題です。 「help logscale」とすれば、ちゃんと logscale のヘルプが見れるので、 これは結構基本的なバグで、 これに悩んだユーザも多少いるのではないかと思います。 今回、CVS 版ではそれがちゃんと修正されました。 ただし、5.0.2 ではまだ直ってはいないようです。
そして、9. が最も目玉ですね。 do for がサポートされたころから、 いずれは配列変数が実装されるだろうと思っていましたが、 ついにきました。 これで、また一段と gnuplot の可能性が広がるだろうと思います。 配列変数は、先に array コマンドでサイズの宣言を行いますが、 C 言語のように外延的な定義もできます。 マニュアルには、以下のような使用例が書かれています。
array A[6] A[1] = 1 A[2] = 2.0 A[3] = {3.0, 3.0} A[4] = "four" A[6] = A[2]**3 array B[6] = [ 1, 2.0, A[3], "four", , B[2]**3 ] do for [i=1:6] { print A[i], B[i] }これを見てわかりますが、 配列の各要素のデータ型は同じである必要はありません。 また、A[5], B[5] は上の例では「undefined」になります。
また、plot や stat, fit などに、 データファイルの代わりに配列を直接与えることもできます。 その場合、配列の要素をデータファイルの 1 列目、 配列の値をデータファイルの 2 列目、と解釈します。 マニュアルには以下のような例が載っています。
array A[200] do for [i=1:200] { A[i] = sin(i * pi/100.) } plot A title "sin(x) in centiradians"
多分、今後色んな使い道が示されていくことになるだろうと思います。 私も有益な例を見つけたらここで紹介したいと思います。
(cf. 「情報やメモ (05/10 2016)」)
気がつくのが遅れましたが、今年の始め (01/04 2016) に gnuplot-5.0.2 がリリースされていたようです。 現在はマイナーバージョンは、半年毎に出る予定になっていますから、 順当な更新だと思います。 5.0.1 から 5.0.2 への新規機能、変更、修正は以下のようです。
見てわかる通り、主に修正と小さい変更です。 日本語マニュアル もようやく更新しておきました。
(cf. 「情報やメモ (2016 07/29)」)