ページが長いので「しおり」の仕組みを用意してみました。
「しおり用」と書かれた所をクリックしてからブックマークに入れると、
それはページの先頭ではなく、その箇所へのブックマークになります。
(03/03 2006)
「情報やメモ (12/08 2011)」 でも紹介しましたが、 現在の開発版 (4.5) の MS-Windows バイナリのインストーラ付きのものが 以下に置かれています。
ここにある gp45-20XXXXXX-win-mingw.exe がインストーラ版の MS-Windows バイナリ (MinGW コンパイル版; version 4.5) になっています。 インストーラでは日本語を選択することもできて、 「日本語対応」もインストールすると (全部で 50MB 弱が必要)、 メニューやヘルプもデフォルトで日本語になります。
なお、インストーラの途中に出る日本語文書で、 英文と日本語訳が中途半端に並列してたりするものがありますが、 それは訳のチェックのために原文もつけたものを送ったら それがそのまま採用されてしまったためです。 改善したものも報告しておきましたので、 今後そのあたりも改善されるだろうと思います。
前回の報告 (10/06 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
2 ヶ月位報告をためていたので、かなり分量が多くなってしまいました。 主要な部分を pick up すると以下のような感じでしょうか。
1. は、長さを指定した (例えば一定) ベクトル群を書くのに便利です。
2. は、zlabel の場所に関する仕様変更です。従来の Z 軸のラベルは、 splot でマウスでグリグリ動かしてみるとわかりますが、 Z 軸に対して固定の位置ではなく、Z 軸の左にあったり上にあったり下に行ったり、 と見る角度によってその場所が変わります。 それを、常に Z 軸に対して左の一定の距離を保つ位置に置くようにしたようです。
3. は、データの x 座標に度分秒のデータを許すようにしています。 なお、角度を表示する度 (°) の記号ですが、 オリジナルは UTF-8 で表現されています (C2B0h = U+00B0) ので、 UTF-8 以外の日本語環境では、 そのままでは座標表示 (左下角のマウス座標) が文字化けしてしまいます。 その場合、「set encoding locale」を実行してみてください。 「show decimal」で全角の「°」が表示されると思います。
4. は demo/boxplot.dem を参照してください。 例えば以下のようなものが書けるようです。
5. も demo/pm3d.dem を参照してください。詳しくは、 以下の論文を参照、とのことです。
9., 10. は、 windows 版の改良を精力的に行っている Bastian Maerkisch さんの寄与で、 9. は、国の情報を MS-Windows から読みとって、日本の場合には自動的に wgnuplot-ja.chm, wgnuplot-ja.mnu を読み込むようにするもの、 あるいはその国情報を後から強制的に変更するためのものです。 これにより日本語化キットの導入時のファイルの名前の変更等の設定が 今後不要になります。 さらに、日本の場合には日本語のデフォルトフォントの設定も行われるようです。
10. は、CVS 版に既に付属している gnuplot-ja.doc から MS-Windows 版の日本語 HTML ヘルプ wgnuplot-ja.chm を MinGW 環境で自動的に作成できるようにしたものです。 wgnuplot-ja.chm の作成にはちょっと面倒臭い手順が必要なので、 うちのサイトで wgnuplot の日本語キットとして公開していたのですが、 これによりそれも不要になるかもしれません。
なお、Bastian Maerkisch さんは現在 CVS 版の MS-Windows 用のインストーラを作成していて、 その日本語化も行われています (私も少し協力しています) ので、 今後 MS-Windows ユーザにはより導入しやすくなるかもしれません。
11. の cairolatex terminal は、epslatex terminal と同様に 画像と文字を分けて出力します。 画像は cairo + pango で EPS か PDF、文字部分は LaTeX 形式での出力です。 画像部分は pngcairo/pdfcairo/epscairo と同様の出力になります。 また、12. の context terminal は、ConTeXt という TeX 系のシステムの文書中から gnuplot を呼び出して、グラフを挿入するような仕組みのようです。 詳しくは以下参照。
13. は、wxt terminal のグラフ上で、 凡例 (key) 部分がトグルスイッチになっていて、 それをマウスでクリックすると、 そのグラフが消えたり再び表われたりする仕組みです。
14. は、以前 (「情報やメモ (11/14 2011)」) は次期版は 5.0 にする、という話も出ていたのですが、 結局、開発版を 4.5 のままにして次のバージョンは 4.6 にして、 4.6-stable にはバグの修正や安定した新機能を追加し、 ある程度のリリース時期 (だいたい 6 ヶ月毎と言ってるようです) がきたら 4.6 をリリースし、開発版は 4.7 にする、 という方針でいくようです。よって、4.[奇数] が開発版、 4.[偶数] が正式リリース版、というこれまでの方針は しばらくは継続されるようです。
現在の CVS 版の wgnuplot の日本語環境に関する改良が行われました (by Bastian Maerkisch)。
これで、今までは日本語キットの導入時に、
ファイル名の変更などが必要だったものが今後は必要なくなりますし、
より多くの言語用のメニューファイルやヘルプファイルに
対応できる可能性が広がりました。
現在は、とりあえず GetLocaleInfo() が "JPN" の場合に
"-ja" をつけて探すことだけがサポートされています。
# 付属ドキュメントも更新しないと...
また、最近気がついたのですが、 以前は wgnuplot の入力画面で日本語を入力すると、 一旦その画面では日本語が化けていて、 それをヒストリで読みだしたり他のウィンドウで一度隠したりすると 正しく日本語が表示されるようになっていました。 それが、5 月位の CVS 版からは ちゃんと最初から日本語が化けずに表示されるようになっています。 気がつきませんでしたが、 3 月後半から 5 月にかけては wgnuplot にかなり手が入っているので、 その際に修正されたのだろうと思います。
2 ちゃんねるの掲示板「gnuplot を使おう。その 3」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
MS-Windows 7 で EPS ファイルを出力する際、 日本語フォント指定をすると半角部分の文字間隔が広くなってしまう、 という質問がありました (25)。
フォント指定を変えてみるとうまくいく、 というような回答がついていましたが、 元々は以下に書いてある内容に関する記事のようです。
上のページの最後にも書かれていることに関することも含め、 MS-Windows で EPS を作る場合の注意について、少し説明をしておきます。
set terminal postscript eps enhanced
jfont = "GothicBBB-Medium-90ms-RKSJ-H"
set xlabel "泌乳日数" font jfont.",20"
...
set ylabel "{/".jfont." 乳量} (kg)"
font ",20"
# または set ylabel sprintf("{/%s 乳量} (kg)", jfont)
font ",20"
なお、上記 Web ページの例では凡例 (key) でも 日本語と半角英数が混在しているのですが、 そのフォントを使い分ける場合は set key では font 指定はせず、 enhanced モードを利用した使い分けるといいでしょう。 ただ、それをいちいち書くのは面倒なので、
mytitle(n) = sprintf("{/%s=20 雌牛} %d", jfont, n)
...
plot [1:300][0:35] 35.0-0.09*x-18.0*exp(-0.05*x) title mytitle(1),\
30.0-0.06*x-15.0*exp(-0.05*x) title mytitle(2), \
25.0-0.03*x-10.0*exp(-0.05*x) title mytitle(3)
のように key タイトル文字列を返す文字列値関数を定義して使うと
楽だと思います。
gnuplot-4.4.4 が先日 (11/12) リリースされました。 配布物に含まれる NEWS には、以下のように書かれています。
gnuplot 4.4.4 での新しい機能、変更、修正
以前紹介したものもありますし、 あまり記憶のないものもありますが、4.4 系列ということで、 現在の CVS 版 (4.5 系列) に追加されているたくさんの新しい機能に比べると あまり大きな変更はないようです。
開発者から、次のリリース版のバージョンは 5.0 にしたい、 という意見も出ているようですが、 現在の CVS 版は確かにかなり大きな変更が行われているので、 リリースされるとインパクトは強いと思います。
なお、日本語マニュアル、MS-Windows 用の日本語化キットは、 既に公開 しています。
(cf. 「情報やメモ (12/08 2011)」)
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」「その 3」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
なお、「gnuplot を使おう。その 2」は 1000 に近くなったので、 現在は「gnuplot を使おう。その 3」に移行しているようです。
set ylabel で簡単な文字列 ("hoge") を与えたら gnuplot-4.4 + png terminal でエラーがでる、という質問がありました (918)。
その後、以下のような追加情報もあげられていました。
上の 1. のエラーメッセージは、フォントは開けているんだけど、 回転を伴う描画時に失敗している、gd ライブラリが出すメッセージです。 しかし、2., 3. からすると、gd 自体の問題というよりも、 掲示板にも回答があったように、 その下請けの FreeType ライブラリの問題の可能性もあります。
元記事の人は Debian squeeze を使っていて、 それが使う FreeType ライブラリは 2.4.2 位のもののようです。 ただ、問題を特定するには、 実際に参照しているフォントがなんであるかも特定する必要があります。 上には参照しているフォント名も表示しているようですが、 実はそれを表示しているのは gnuplot の方で、 つまり指定されたフォント名を表示しているだけです。 最近の gd は fontconfig を参照しているので、 実はそれを指定したつもりでも 別なフォントが使われているという可能性がないわけではありません。
回転が 89 だといいのに 90 だとだめ、 というのはあまり見たことがありませんのでよくわかりませんが、 まずは問題を再現できる環境を特定することでしょうか。
ちなみに、gd-2.0.35 と freetype-2.3.9 (FreeBSD) で、 FreeBSD で入れたいくつかの TrueType フォントでテストしてみましたが、 問題は再現できませんでした。 上記の名前のフォントをダウンロードして試してみましたが、 全く問題はありませんでした。
multiplot で目盛りを固定して凡例だけずらすには、 という質問がありました (944)。
回答はついていませんでしたが、例えばこういうことでしょうか。
set title "multiplot test" font ",14"
set lmargin at screen 0.12
set bmargin at screen 0.12
set tmargin at screen 0.90
set rmargin at screen 0.95
set xrange [-10:10]
set yrange [-2:2]
set xlabel "hoge"
set ylabel "fuga"
set multiplot
plot sin(x)
unset title
unset xtics
unset ytics
unset xlabel
unset ylabel
unset border
set key at graph 0.985, 0.94
plot cos(x) lt 3
unset multiplot
lmargin, bmargin 等でグラフの枠を固定できますが、 key を簡単にずらすのはできないので、 「set key at」で直接位置を指定しています。 その数字は試しながら調整します。
ただ、確かに multiplot 用に、 簡単に key をデフォルトの位置からずらすようなオプション (offset) を追加するといいかもしれませんね。
3 次元データの断面のグラフを表示したいようで、 MATLAB のサンプルのようなことができないか、という質問がありました (964)。
gnuplot は単なるグラフ描画ソフトなので、この手の処理、 すなわち任意の断面の状態 (pm3d) の表示をすることはできません。 これには高度なデータ処理を必要とするからです。
ただし、回答もついていたように (967) データが特別な形をしていて、 その特別な方向への複数の断面を表示させるだけなら可能です。 まず、以下のような awk スクリプトでデータ test.dat を作成します:
BEGIN{ for (z=-1.0; z<=1.0; z+=0.1) for (y=-1.0; y<=1.0; y+=0.1) { for (x=-1.0; x<=1.0; x+=0.1) printf "%f %f %f %f\n", x, y, z, f(x, y, z) printf "\n"; } } function f(x, y, z) { return (3-x*x-y*y-z*z)/3.0 }これは、メッシュ状のデータを作成します。 データの各行は x,y,z の各座標とそこでの f(x,y,z) の関数値で、 x 方向の走査が終わるたびに空行を入れています。
これは、21 ブロックずつが同じ z 座標を持っているので、 以下のようにプロットすれば、各 z の面の pm3d 面を得ることができます。
set xrange [-1.0:1.0]
set yrange [-1.0:1.0]
set zrange [-1.0:1.0]
splot for [j=0:20:5] 'test.dat' every :::(j*21+0)::(j*21+20)
with pm3d not
splot の mouse による視点を移動を行うと少し面白いです。
「plot 'data' using 0:1, '' using 0:(a=$1+$3) axes x1y2, '' using 0:(-(b=$2+$4)) axes x1y2, '' using 0:(a-b) axes x1y2」 は期待通りにならない、という意見がありました。
gnuplot の「plot A, B, C」は、 データファイルから 1 行データを取って並列に A, B, C を描画し、 という形で進むのではなく、 そのデータファイルに対して A を全部描画し、 次に B を全部描画し、 次に C を全部描画し、と進むので、これがうまくいかないのは当然です。
けど上は、a-b の代わりに ($1+$3)-($2+$4) と書けばいい程度なんですがね。
MS-Windows を起動した後の wgnuplot が最初に plot するときに 時間がかなりかかる、という質問がありました (972)。
これは fontconfig が、フォントのキャッシュデータを 作成しているためのようです。 それを、一時的なディレクトリではなく、 固定したディレクトリにすれば解消するらしいです。 以下に情報があります。
また、松岡版の wgnuplot ではこれは起きない、という話もありました。
「情報やメモ (10/11 2011)」 にも少し書きましたが、 MS VC++ でコンパイルした gnuplot で all.dem を見ていたら、 stringvar.dem のところで止まってしまいました。
3 つ位エラーみたいなものが出るのですが、 そのうち 2 つは system() に関するもので、 「set label 1 system("cat stringvar.tmp") ...」 という行と「"`date`"」という行が出してくる 「warning: system evaluation not supported by MS-Windows 32 bit」 というものです。 これは、実は「MS-Windows 32 bit」とかということとはあまり関係なく、 直接はコンパイル時に PIPES というマクロが定義されていない、 ということを意味します。 MS-Windows アプリケーションには、 MS VC++ は popen(), pclose() を持たない (別な仕組みを使わないとだめ) のでそうなっていますが、 コンソールアプリケーションの gnuplot.exe なら、 MS VC++ にある _popen(), _pclose() で代用できそうです。
ただ、いずれにせよこちらは warning なので大きな問題ではないのですが (実際に止まってはいない)、問題はその後に起きるエラーの方で、
foo = sprintf("%40d %40d %40d %40d ...
のような行に対して、「undefined value」と言って止まってしまいます。
調べてみると、
foo = sprintf("%83d", 1)
ならいいのに、
foo = sprintf("%84d", 1)
だと同じエラーとなってしまうことがわかりました。
私も何が原因かよくわからず、 エラーメッセージからして gnuplot の式の evaluation がからんでいる厄介な問題のような気がしたので、 本家の ML に投げてみたら、MS VC++ では snprintf() の代用として _snprintf() を使用していて、 そのあたりに問題があるらしいことがわかり、 その後調べてみたところ、この _snprintf() は普通 (ANSI C) の snprintf() とは以下のように仕様が違うことがわかりました。
'\0' をつけないのもかなり危険ですが、 errno に ERANGE を設定することが結果的に上のような「undefined value」 を出すことになっていました。
それに対するクイックハック (あんまり綺麗じゃない) のパッチを送り、現在は一応それが採用されていますので、 この問題は MS VC++ でも起きないようになっています。
なお、角藤版の CVS 版の gnuplot は VC++ でのコンパイルなので、 ある時期から最近まではこの問題が起きていたようですが、 松岡版は MinGW でのコンパイルなのでこの問題は起きません。
なお、コンソール版の gnuplot.exe で _popen()/_pclose() を使って PIPES を定義してコンパイルするようにしたパッチも本家に送ってみました。 採用されたらまた報告します。
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
大量のデータからなるデータファイルで、データを間引き (every)、 かつ曲線補間 (smooth) したいのだけど、という質問がありました。
それぞれは使えるんだけど、 両方を反映させるような文法は探し切れませんでした、 ということでしたが、 同時に指定するのは単純にその指定を両方並べればいいだけだ、 という例つきの回答がありました。
help every を見ると「plot 'file' every ...」と every のことだけ書いてあり、 また help smooth には smooth のことだけ書いてあるので、 両者を同時に指定することができない、と勘違いしたのかもしれませんね。 正しくは、help plot datafile を見てもらえば、 両方が同時に使えることがわかったのかもしれません (けど、ここにたどりつくのは簡単ではない ?)。
(2505 の記事から始まるスレッド 「smooth と every の同時使用について」)
松岡さんが、別の記事 (2512 番) で、 MinGW でコンパイルした gnuplot.exe で Windows 7 上で不具合が起きている、 ということを書いておられたので、 多少解決に協力しようかと思いつきをいくつか書いてみたのですが、 私の予想はことごとく外れて (^^;) どうやらリンクしている HTML HELP workshop のライブラリの版の問題のようでした。 一応現在のところこの問題への対処は行われているようです (「情報やメモ (05/23 2011)」 参照)。
(2513 の記事から始まるスレッド 「Win7 での不具合」)
CVS 版での改良、sorceforge.net での gnuplot のダウンロード状況 に関する情報などを投稿しました。
最後のものにありますが、gnuplot をダウンロードしているのは、 国別に見るとアメリカ、日本が飛びぬけて多いです (私が見たときはたまたま 1 位)。 日本は、gnuplot に関するいい本がいくつか出版されていることや、 この松田さんの掲示板のページやうちのマニュアルの日本語化、 その他 gnuplot に関する多くの日本語の Web ページなど、 日本語の情報が多いことが影響しているのだろうと思いますが、 なんとなくもう少し別な要因がありそうなくらい多いですね。
空間の 4 点が同一平面上にない場合、gnuplot の splot with pm3d で表示し、 マウスでぐりぐり回してみると妙な形になっていることに気がつきます。 裏から表を見るように切りかわる場合に形が変わります。
gnuplot の仕様からしてバグとまでは言えないように思いますし、 通常はこれほど少ない点数での表示はしないので問題はないだろうと思いますが、 ちょっと意外でした。
実は、with pm3d は、4 点からなる四辺形を基本に塗っていくので、 それが平面ならば法線方向が決まり、それと光の方向との内積を計算すれば、 レイトレーシング風の色づけを実装できるのでは、 と考えたのですが、ふと、その四辺形が平面でないとどうなるんだろう、 とやってみたのがこれでした。
差分による近似的な微分でレイトレーシング風の描画を gnuplot で行っている方もおられるようですが (米澤進吾@京大 さん)、 それだと gnuplot に実装するのは面倒です。 単純に 4 辺形に法線を決められれば簡単なのですが、 こういう問題があると、多分大抵の滑らかな曲面の場合は問題ないのですが、 そうでない場合はちょっと変になるかもしれません。
(2545 の記事 「少ない点に関する splot」)
demo/poldat.dem を見ると、 「plot "-" using 1:5, "-"」のような行があり、 その下に直接データが書いてあるが、 この "-" の使い方、およびその下にある e は何か、 という質問がありました。 一応は、「help special」「help special-filename」 等で解決する話なのですが、 少し考えるべきこともあるように思います。
質問者は付属の説明書では探しにくい、とも書いていましたが、 確かに help - でも help e でもそれらの説明はでてきません。 質問者は MS-Windows 版を使っているようでしたが、 それらを正しく検索するのは容易ではありません。 これは、現在のヘルプファイルの肥大化に伴う問題、 と考えることもできると思います。
ファイル名としての "-" の記法は、 gnuplot-3.7 で導入されたものなのですが、 その前の gnuplot-3.5 の頃の gnuplot.doc は 3631 行、 gnuplot-3.7 の gnuplot.doc は 6648 行、 そして現在の最新版の gnuplot-4.4.3 の gnuplot.doc は 12149 行、 開発版の gnuplot.doc (rev 1.694) は 13304 行もあります。 簡単に探せなくなっているのは当然です。
また、gnuplot-3.7 の頃は、 「help introduction」の中に "-" に関する話も出てきます。 現在は、この他にも特別なファイル名が追加されたので 単独のセクションに分離してしまい、 「help introduction」では触れられてはいないのですが、 昔の形であれば見つけていた可能性もありますね。
何らかの tutorial が必要か、 あるいは help introduction の改善の必要がある、 ということを意味しているのかもしれません。 個人的には、ソフトの説明書は 「初心者向け」 「中程度 (一般的なこと)」 「詳細なもの (リファレンス)」 の 3 段階があることが理想だと思いますが、 現在の gnuplot.doc はほぼ「詳細」なことが多く書かれていて、 かつ、中には「中程度」や「初心者向け」のようなセクションも いくつか含まれています。 もしかしたら、その辺りを整理すると多少は良くなるのかもしれません (が、あまりに巨大すぎて見通しが立たず...)。
(2546 の記事から始まるスレッド 「poldat.demについて」)
新しく導入された stats コマンドについて紹介しました。
するとそこから派生して、gnuplot ボランティアの作業、 all.dem の自動進行の方法、 最近送った MS VC++ でのコンパイルの際のパッチの話、 などに話が広がりました。
Unix の X11 環境では、demo/ ディレクトリ内で
../src/gnuplot all.dem < /dev/null
とすると、デモがすべて自動的に流れていきます。
MS-Windows では /dev/null の代わりに nul とするだけではだめなようで、
改行コードを送り続ける必要があります
(最初は "y" という文字も必要かと思った)。
よって、空行が 1000 行位並んだファイル n.dat を使って
..\src\gnuplot.exe all.dem < n.dat
とするか、gawk を使って
gawk "BEGIN{while(1) print}" | ..\src\gnuplot.exe all.dem
のようにすれば、すべての pause に自動的に答えることになって、
何もしなくても all.dem が進行するのを眺められます。
(2549 の記事から始まるスレッド 「stats コマンド」)
[実数部分][空白][虚数部分][改行]、のようにデータが並んでいる データファイルを描画したいのだが、という質問がありました。
これに対し、複素平面上に書くだけならば、 x+yi と (x,y) は同じ点を意味するので、 普通の (x,y) の散布図と同じ、 つまり「plot "ファイル名"」でいいのでは、 という回答がありました。
gnuplot はデータとして複素数も使えるのですが、 そのせいで逆によくわからなくなる場合もあるのかもしれませんね。
(2560 の記事から始まるスレッド 「複素数のプロット」)
(cf. 「情報やメモ (10/11 2011; no.2)」, 「情報やメモ (03/23 2016)」, 「情報やメモ (10/07 2016)」, 「情報やメモ (05/09 2018)」)
前回の報告 (08/28 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回は、また win term (wgnuplot) への改良がかなり入りました。 それに伴って、wgnuplot のウィンドウ、グラフウィンドウの見た目が 従来のものからかなり変わっています。 特に、グラフウィンドウのツールバーと 描画要素を消す/戻すためのハサミのアイコンの追加は大きな違いです。
post.trm に関連する {no}background による背景色指定や epscairo の {no}crop のサポートも新規機能として期待されます。
emf terminal の set encoding sjis の件は、 「情報やメモ (08/28 2011)」 で前回報告した、utf8 の場合に実装された UTF-16 への変換に関して、 「Shift_JIS の場合もこれと同じように iconv を使って UTF-16 に変換するようにすれば」という話を実際に実装したものです。 これで、Shift_JIS 環境でも emf terminal の出力ファイルで OpenOffice でクラッシュする問題が改善されます (set encoding sjis を使用)。 ついでに LibreOffice でもテストしてみると、 従来の emf terminal の Shift_JIS 環境の出力は LibreOffice では日本語部分が文字化けしてしまいますが、 今回の対応が含まれたものの emf terminal の出力は正しく表示されました。 これは、 gnuplot Q&A 掲示板 の 2541 番の記事でも報告しています。
svg terminal でフォント名に Bold, Italic の属性をつけるというのは、 フォント名として例えば "Arial Bold Italic, 12" のように指定すると、 svg の方には、
style="stroke:none; fill:black; font-family:Arial;
font-size:14.00pt; font-weight:bold; font-style:italic;
text-anchor:end"
のように font-weight と font-style を変更するようになりました。
最後にですが、前回からの変更の最大の目玉はなんといっても stats コマンドでしょう。 これは、plot や splot と同様の書式で使用します:
stats "datafile" [using col1[:col2]] [nooutput]
[name "PREFIX"]
plot や splot とは違い、グラフの描画はしませんが、
データファイルを読んで、その統計情報を画面表示し、
それを決められた変数に保存します。
よって、それらを後の描画で利用できます。
取得する統計情報は、マニュアルによると現在のところは以下のものです:
これらのうちいくつかは、 カンマ演算子と plot によるデータの空読みを組み合わせたり、 fit コマンドを利用することなどでも取得することができたものがありますが、 そのような苦労をしなくてもよくになります。 特に、描画範囲を決定したり、複数のグラフの位置関係を制御するのには、 最大値や最小値のデータは重要でしょうし、 それを与える x 座標などもグラフの制御には有益だと思われます。
gnuplot は統計ソフトではありませんが、 簡単な統計グラフであれば、これらによって書けることになりますね。 個人的には、データを外部処理しなくても、 グラフのタイトル (やラベル) に 相関係数値を入れられるのはいいかなと思いますし、 メジアンや平均値をグラフに重ねて別な色の縦線などで明示できるのも 面白いかなと思います。
stats を利用するデモも追加されていますが、 最大値、最小値などを表示するようなもののようです (まだ見ていません)。 何か面白い使い方があったら、また適宜紹介していきたいと思います。
(cf. 「情報やメモ (12/08 2011)」)
前回の報告 (07/26 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
古いドライバが 2 つ (rgip, mgr) 削除されましたが、 目立つ変更点は、以下の 3 つでしょうか。
一つ目のものは、X11 などの対話型出力形式では既に実装されていたものですが、 「set term win 1」「set term win 2」のようにして、 一つの gnuplot 上から複数のグラフウィンドウを生成する仕組みの実装です。 ついでに、set terminal win の font 指定オプション、 background (背景色) のオプションなどが変更/追加されています。
2 つ目のものは、元々はだいぶ前に議論されていたものだったと思います。 「情報やメモ (11/08 2008)」 に書いたように、gnuplot でも再帰関数を使えば関数列の和の式を作ることが ある程度可能なのですが、 iteration の実装の一環として、和の機能自体が実装されました (by Micha Wiedenmann)。 以下のような書式で使います:
sum [<var> = <begin> : <end>] <一般項>例を上げます (前者はドキュメントにある例):
# plot 'data' using 1:($2+$3+...+$N) と同等
plot 'data' using 1:(sum [col=2:N] column(col))
pause -1
# sin(x) のテイラー展開
f(k,x) = (M=2*k-1, (-1)**(k-1)*x**M/M!)
set grid
set xrange [-6:6]
set yrange [-2:2]
plot for [j=1:5] sum [i=1:j] f(i,x) title sprintf("%d",j) , sin(x)
pause -1
今まで前者のようなものは、コメント部分にあるように列挙して書き上げるか、
または awk などで前処理するしかなかったのですが、
これが gnuplot でできるようになりました。
また、これまで再帰関数で実装できた後者のようなものも、
こちらの方がはるかにわかりやすいだろうと思います。
3 つ目のものは、「情報やメモ (2011 07/15)」 で報告した 1 行目のラベルで using 指定することと関連するものです。 例えばデータが以下のようなものだとします:
番号 国語 算数 理科 名前 1 60 70 95 花子 2 80 50 55 太郎 3 50 90 70 次郎 4 70 80 75 三郎
このデータを using のラベル指定で出力できることは前に説明した通りですが、 with labels を使う場合、
using 1:"国語":"名前" with labels
とすると、最後の「"名前"」の部分が column() によって処理されて、
すなわち数値とみなされてしまってうまく文字列が表示されない、
ということに対応するために、stringcolumn() (strcol())
でもラベルへの対応が行われ、
using 1:"国語":strcol("名前") with labels
とすることが可能になった、というのが 08/25 の改良です。
しかし、その後さらに改良が行われ、
using 1:"国語":"名前" with labels
でも、"名前" の部分がちゃんと文字列として評価されて
表示できるようになった、
というのが一番上の 08/27 の改良です。
なお、emf ドライバの改良として「UTF-8 文字列を UTF-16 に変換するように」 というものが入っていて、これは iconv を使って実装されているのですが、 そのようにしない EMF ファイルを OpenOffice で読み込むとクラッシュするため、 と報告されています。 これは、「情報やメモ (01/07 2011)」 でも紹介しましたが、 gnuplot Q&A 掲示板 で松岡さんが 2391 番の記事で報告していた問題と同じものです。 よって、Shift_JIS の場合もこれと同じように iconv を使って UTF-16 に変換するようにすれば、gnuplot 側で解決できることになるでしょう。
(cf. 「情報やメモ (10/06 2011)」)
前回の報告 (06/23 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
大事なものは、既に 「情報やメモ (07/15 2011)」 で報告済みですが、2,3 説明します。
まず、「目盛りラベルの位置合わせの明示のサポート」は、 set tics, set xtics 等に追加された left|right|center|autojustify のオプションを意味します。
「fillsteps でバイナリデータを扱えるように」は、 単に fillsteps をサポートするためのエントリを入れ忘れていただけのようですが、 「xticlabels() をバイナリデータでも使えるように」の方は、 実際にバイナリデータから文字列を取得するわけではなく、 文字列関数として利用することのようです (自信 & 検証なし)。
(cf. 「情報やメモ (08/28 2011)」)
最近また 2 つほど大きな機能が CVS 版の gnuplot に追加されましたので報告します。
一つ目は iteration のネストです。 例えば、「set for [i=1:3] for [j=1:10]」、 「plot for [i=1:3] for [j=1:10]」のような 2 次元的な繰り返しも可能になります。 これにより、 「情報やメモ (06/23 2011)」 に書いた、set for と do for を用いたベクトル場の描画は、 do for なしに書けることになります:
# 傾き f(x,y) のベクトル場を表示 f(x,y) = 1.0 - y Ax(x,y) = 0.2 # ベクトルの x 成分 Ay(x,y) = Ax(x,y)*f(x,y) # ベクトルの y 成分 set xrange [0.0:5.0] set yrange [-1.0:2.0] set yzeroaxis sx = 0.01 # do for の整数変数のスケール変換用 sy = 0.01 # set for の整数変数のスケール変換用 set for [j=0:499:25] for [k=-100:200:25] arrow from j*sx,k*sy \ to j*sx+Ax(j*sx,k*sy),k*sy+Ay(j*sx,k*sy) lt 4 set title "傾き (1-y) のベクトル場" plot 1/0 not # ダミーplot で for の入れ子を行うサンプルはあまり考えつきませんが、 何かあったら教えてください。
もう一つが using の列 (column()) 指定で、 文字列指定が可能になった点です。 その文字列とは、データファイルの 1 行目にあるラベルです。 例えばデータが以下のようであるとします:
番号 国語 算数 理科 1 60 70 95 2 80 50 55 3 50 90 70 4 70 80 75
これまで、このデータの 1 行目のラベルは、 columnhead() で使用したり (help datastrings 参照)、 key() でヒストグラムのタイトルとして使用したり (help histograms 参照) できましたが、 今回さらにこのラベルで列指定を行うことができるようになりました:
set pointsize 3 set xrange [0.5:4.5] set yrange [20:100] set grid set xtics 1 set title "column() による文字列 (列ラベル) のサポート" plot "data" using 1:"国語" with lp, \ '' using 1:(column("算数")) with lp,\ '' using "番号":"理科" with lp title columnhead(4)
直接 using 指定にこのように文字列を書くこともできますし、 column() の引数に文字列を指定することもできます。 なお、plot の 3 つ目のものは「title columnhead(4)」がないと グラフタイトルが「理科」ではなく「番号」となってしまいます。 どうやら、y 座標で使われているものをタイトルとしているのではなく、 最初にラベルとして使われたものをタイトルとしているようですので (多分 set key autotitle columnheader の挙動)、 改めて columnhead(4) で 4 列目の先頭のラベルを選択しています。
これは、複数のデータを paste ではりつけたといったような理由で 欲しいデータが何列目にあるかがわからない、あるいは不定な場合に、 特定のデータを選択するといった目的には便利だと思います。
gnuplot Q&A 掲示板 で松岡さんから指摘がありましたが、 「情報やメモ (07/04 2011)」 に書いた、 MS-Windows 上で pipe で gnuplot.exe を呼び出した場合に pause -1 が効かなくなる部分の話は、 MS-Windows 特有の話ではなく、Unix 上の gnuplot でも共通の問題でした。
なお、現在は pipe 経由の場合も mouse を使って pause ができるので、 自分のソフトでグラフを書かせたい場合に、 外部ソフトとして gnuplot を利用することの良さが かなり広がっているように思います。 pipe 以外の方法として、スクリプトファイルを作っておいて system() で gnuplot を呼び出すという方法もありますが、 pause mouse があれば、 リアルタイムで gnuplot を制御できる pipe 経由の方が ずっと良さそうな気がします。
(cf. 2529 の記事から始まるスレッド 「Windows コンソール版のgnuplotのpauseについて」)
ふと、MS-Windows 上で C から pipe を使って gnuplot を呼び出すプログラムを書いて実験してみました。 そのときに気がついたことをまとめておきます。 使用したのは CVS 版の gnuplot (4.5) です。
C のコンパイラとしては Borland C++ 5.5 を使用しましたが、 まずパイプが使えるか心配だったのですが、 popen(name,mode), pclose(fp) として、 _ を前につけた _popen(name,mode), _pclose(fp) を使えばいいことがわかりました。
次に、pgnuplot.exe と gnuplot.exe を確認してみました。 pgnuplot.exe は wgnuplot.exe を実行していますので、 pause 命令で pause ウィンドウが開きますが、 コンソール版 gnuplot.exe はコマンドプロンプトの方に「paused」 のように表示されるだけのようです。
その pause の動作ですが、pgnuplot.exe の方は特に問題はなかったのですが、 gnuplot.exe の方が気になりました。
まず、gnuplot.exe はコンソール版ですから、 コマンド入力はコマンドプロンプトで行います。 しかし、グラフウィンドウが前面に出ているために、 コマンドプロンプトにアクティブウィンドウを切り替えてから (それでグラフウィンドウが後面に下がる) でないと pause 処理ができないのがやや不便かなと思いました。
しかも、その pause なのですが、 実はコマンドプロンプトの標準入力は gnuplot.exe をパイプで呼び出している C のプログラム側が持っていますので、 gnuplot コマンドである「pause -1」の方は 標準入力を取得することができず、 コマンドプロンプトで return を入力しても「pause -1」には反応しません。 これに対処するには、2 つの方法があります:
前者は、以下のような処理:
plot sin(x)
pause -1
plot cos(x)
pause -1
を行う際は、C では以下のよう書く、という方法です:
FILE *pipe;
pipe = popen("gnuplot.exe", "w");
fprintf(pipe, "plot sin(x)\n");
fflush(pipe);
getchar();
fprintf(pipe, "plot cos(x)\n");
fflush(pipe);
getchar();
pclose(pipe);
後者は、むしろ以下のように pause 命令を発行する方法です:
FILE *pipe;
pipe = popen("gnuplot.exe", "w");
fprintf(pipe, "plot sin(x)\n");
fprintf(pipe, "pause mouse(x)\n");
fflush(pipe);
fprintf(pipe, "plot cos(x)\n");
fprintf(pipe, "pause mouse(x)\n");
fflush(pipe);
pclose(pipe);
こうすれば、マウスクリックで pause が解除されます。
しかもこの後者の方法ならば、
コマンドプロンプトに戻らなくてもいいので、
上の 3 つ目の問題も解消することになり、
むしろ pgnuplot.exe よりもこちらの方が便利なくらいです。
(cf. 「情報やメモ (07/07 2011)」)
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
関数 plot の描画範囲を描画領域より狭めたい、という質問がありました (906)。 例えば xrange は [0:5] なんだけど、関数は [1:4] の範囲で描画したい、 といった要望のようです (棒グラフとの関連)。
それに対して、0/0 を使って関数描画のグラフをカットする方法が 紹介されていました (前に紹介されたものを引用する形)。 当然これが最も自然な方法でしょうが、他にも 2 つほど手は考えられます。
ひとつは、関数描画の方も一度 table 出力を行ってデータ化して、 それを再び読み込んで描画する、という手です:
set xrange [1:3] # 狭い範囲で table データを作成
set table 'table.dat'
plot sin(x)
unset table
set xrange [0:4] # 範囲を広げる
plot 'table.dat' w l t 'sin(x)', 'data' with boxes fs ..
このようにしても、関数描画となんら変わらない形で描画ができます。
もう一つの手は、媒介変数モード (set parametric) を利用する方法です。 関数の方を trange で制限して t,f(t) と描画すれば、 これもなんら通常の関数描画と変わらずに範囲を制限して描画できます:
set xrange [0:4]
set parametric
set trange [1:3]
plot t,sin(t) w l t 'sin(x)', 'data' with boxes fs ..
fit で決定した定数をタイトルに表示したいのですが、 という質問がありました (907)。
これは、文字列変数が導入された gnuplot-4.2 以降であれば比較的容易で、 sprintf() を使ってそれらの変数を値をタイトルに入れれます:
f(x) = a*x+b
fit [1:3] f(x) 'data' via a,b
set title sprintf("f(x) = %f*x+%f",a,b)
plot 'data' w lp, f(x) t sprintf("f(x) (a=%f,b=%f)",a,b)
指数分布の fitting に gnuplot の fit を使う方がいいか、 それとも分布から計算した平均を使ってλを逆算して決めるべきか、 という質問がありました (911)。
これは、正確に言えば gnuplot に関する質問、 というよりも統計に関する質問だろうと思いますが、 回答は「理論的に求まるならそちらがいいのでは」ということでした。
確かに、指数分布は一つのパラメータだけで決まり、 それは平均値で決定できますが、 残念ながらそれではあまりいい近似にはならないでしょう。 元々データには誤差があり、 その誤差を考慮して全体のデータになるべく当てはまるものを見つけよう、 というのが「最小二乗法」「fitting」の考え方です。 それを、全データ情報を 1 つの値に集約した「平均値」だけで評価し、 それ以外の情報を無視する、ということを行えば、 いい近似にならないことは明らかでしょう。
もちろん、平均だけで計算することが全然意味がないわけではなく、 例えばそのデータの平均値に強い意味があり、 分布がそれに対する指数分布になっているかを検証する、 といったような場合ならばそうすることも問題ではないとは思います。
関数のパラメータをファイルから読みこんで関数のグラフを書くには、 という質問がありました (914)。 ファイルには、
0.1 1.2 3.5 2.3 0.2のようにデータが入っていて、そのデータを関数に適用した 5 つのグラフを書きたい、という話でした。
これに対し、むしろファイルのデータを元に別なプログラムでデータを作成し、 それを gnuplot に食わせる、といったような回答がありました。 これはしごく真っ当な回答ですが、 これを gnuplot スクリプトだけでできないか少し考えてみましょう。
ファイルを読み込む仕組みとしては、gnuplot には例えば以下のものがあります:
最初の「load を利用」は今回の目的には 一見使えなさそうに見えるかもしれませんが、 必ずしもそうではなく、gnuplot 内部から ! や system を使って パラメータファイルを awk 等で gnuplot スクリプトに加工して読みこむ、 という手があります (要 awk):
f(x,a) = sin(x-a) # a がファイルから読みこむパラメータ
# awk でパラメータファイルの値を gnuplot の代入文に書き換える
# (変数名は a_1, a_2, ..., a_5)
! awk '{for(j=1;j<=NF;j++) printf "a_%d = %f\n",j,$j}'
param.dat > load.gp
# それをロードすれば変数 a_1 ~ a_5 でパラメータ値が参照できる
load 'load.gp'
if (GPVAL_VERSION >= 4.4 && GPVAL_PATCHLEVEL >= 3) \
plot for [j=1:5] f(x,value(sprintf("a_%d",j))) ;\
else \
plot f(x,a_1), f(x,a_2), f(x,a_3), f(x,a_4), f(x,a_5)
最後のところは、別に if 文で書かなくても
どちらかの plot だけを使用すればいいのですが、
gnuplot 4.4.3 以降ならば plot for や value()
が使えるので多少スッキリできます。
ただし、後者の列挙型の plot ならばそれ以前の gnuplot でも十分動作します。
次の「plot 'data' で描画データファイルを読む」 というものあまり使えなさそうですが、 gnuplot-4.4 以降の場合は , (カンマ演算子) と word() を使えば、 以下のようにしてデータを疑似配列に保存することができます:
f(x,a) = sin(x-a)
set term unknown # まずはダミーのデータ読み込み
set xrange [0:1] # ダミーの範囲指定
s = "" # 疑似配列用文字列 (リスト)
# 文字列 s に " p1 p2 .. p5" のようにデータを保存
plot for [j=1:5] 'param.dat'
using 0:(s=sprintf("%s %s",s,strcol(j)), $j)
reset
set term x11
plot for [j=1:5] f(x,word(s,j)) # word(s,j) = pj
using のところがデータを配列に保存している部分で、
sprintf() で j 列目の文字列 (strcol(j)) を s の後ろに追加しています。
これで、ファイル内の「0.1 1.2 3.5 2.3 0.2」のようなデータを、
文字列 s に " 0.1 1.2 3.5 2.3 0.2" として保存できることになります。
そして、その j 番目の単語を抜き出す関数 word(s,j) を使えば
配列的にデータを利用できるようになるわけです。
ちなみに、この方法は gnuplot-beta ML に流れた議論を参考にしています。
最後の「system() を使って外部コマンド経由でデータを読む」 というのが真っ先に考えついた方法です。 簡単には以下のようにします (要 awk):
f(x,a) = sin(x-a)
# system() + awk によるデータの j 列目を返す関数
p(j) = system(sprintf("awk '{print $%d}' param.dat",j))
if (GPVAL_VERSION >= 4.4) \
plot for [j=1:5] f(x,p(j));\
else \
plot f(x,p(1)), f(x,p(2)), f(x,p(3)), f(x,p(4)), f(x,p(5))
見てわかる通り、これが最もシンプルです (gnuplot-4.2 以上) が、
実際には p(j) を使う毎に system() + awk の呼び出しが発生するので、
他の方法よりも時間がかかります。
さらに、plot の title に p(j) の値を利用しようとして、
「title sprintf("f(x,%f)",p(j))」のようなものを追加すれば、
さらに倍の時間がかかってしまいます。
個人的には、2 番目の方法はそれなりにスマートかなと思いますが、 真っ当なのは 1 番目か 3 番目の方法かなと思います。
前回の報告 (05/23 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回は、一見今までに比べると変更は少ないようですが、 かなり重要な改良、新規機能の追加がなされています。 その一つ目が「binary matrix の機能の整理、修正」です。 バイナリデータファイルの場合は binary キーワードが必須、 「binary matrix」に対応して「binary general」というキーワードに整備、 ASCII データ用の matrix キーワードに nonuniform キーワードが追加、 などの色々な変更がなされています。 詳しくはマニュアルを参照してください。
もう一つの大きな改良が、 「if/else ブロックのサポート、do for, while のサポート」で、 これはこれまでの gnuplot には不十分だった スクリプトのプログラミング構造を強化するものです。
まず if 文には { } (中カッコ) を使って複数行のブロック形式で書くこと、 および if 文のネスト (入れ子) がサポートされました。例:
form = "x11" if (form eq "eps") { set term post eps set output "file.eps" tjfont = "GothicBBB-Medium-EUC-H,20" } else { if (form eq "gif") { set term gif set output "file.gif" tjfont = "/usr/local/share/fonts/ipam.ttf,20" } else { set term x11 tjfont = "mbfont:*-fixed-medium-r-normal--24-*" } } set title "if 文の入れ子も使える" font tjfont plot sin(x)前半の設定部分は良く利用するのであれば、 別ファイルにして必要なところで load する、という手も使えるでしょう。
do for は、既に実装されている for の形式で、 複数行からなるブロックを繰り返し実行するためのものです。 for には列挙形式、増分形式の両方が利用できます。例:
# 傾き f(x,y) のベクトル場を表示 f(x,y) = 1.0 - y Ax(x,y) = 0.2 # ベクトルの x 成分 Ay(x,y) = Ax(x,y)*f(x,y) # ベクトルの y 成分 set xrange [0.0:5.0] set yrange [-1.0:2.0] set yzeroaxis sx = 0.01 # do for の整数変数のスケール変換用 sy = 0.01 # set for の整数変数のスケール変換用 do for [j=0:499:25] { # x は 0.25 刻み x = j*sx set for [k=-100:200:25] arrow from x,k*sy \ to x+Ax(x,k*sy),k*sy+Ay(x,k*sy) lt 4 } set title "傾き (1-y) のベクトル場" plot 1/0 not # ダミー
残念ながら do は入れ子にはできないようですが、 set arrow は set for で一次元的には繰り返しの実行ができますので、 上の例で set for arrow で y 方向に繰り返し描画させ、 それを do for で x 方向に繰り返し実行する、 という形で 2 次元的なループを実現しています。
なお、for の増分形式では整数変数しか利用できないため、 上では 100 倍した値をループ変数にして、 それを sx, sy 倍する、という手法を取っていますが、 これはもう一つ実装された while 文を使えばより自然に表現できます:
# 傾き f(x,y) のベクトル場を表示 f(x,y) = 1.0 - y Ax(x,y) = 0.2 # ベクトルの x 成分 Ay(x,y) = Ax(x,y)*f(x,y) # ベクトルの y 成分 # 傾き f(x,y) のベクトル set xrange [0.0:5.0] set yrange [-1.0:2.0] set yzeroaxis x = 0.0 y = -1.0 dx = 0.25 # x の増分 dy = 0.25 # y の増分 while (x < 5.0) { set arrow from x,y to x+Ax(x,y),y+Ay(x,y) lt 3 y = y + dy if (y > 2.0) { y = -1.0 x = x + dx } } set title "傾き (1-y) のベクトル場 (by while)" plot 1/0 not # ダミー
もう一つサンプルを紹介します。 gd ドライバを用いた現在の gif terminal では、 gif animation も作れるようになっています。 従来は、画像列を生成するには、 その分だけ plot 命令を実行するか (plot for は不可)、 if/reread を用いてループを実現するしかありませんでしたが、 この do for か while を使えば簡単に gif animation も作成できます。例:
setenv GDFONTPATH /usr/local/share/fonts set term gif animate delay 10 size 640,480 font "arial.ttf" set out "do-anim1.gif" set title "do による GIF アニメーションサンプル" font "ipag.ttf,14" set xrange [-6:6] set yrange [-2:2] set xzeroaxis f(x,t) = A*cos(w*t*pi)*sin(x-s*t*pi) A = 1.8 # 振幅 w = 0.1 # 0.5w = 振幅の周波数 s = 0.05 # sπ = 1 ステップ毎の横方向のずれ do for [j=0:39] { plot f(x,j) title sprintf("A cos(%3.1f*pi) sin(x-%4.2f*pi)",w*j,s*j) }
このループの実装により、単一のスクリプトで かなり複雑なこともできるようになったと思います。 gnuplot には残念ながら配列変数がないので ループに伴う処理がまだやりにくい部分がありますが、それも 「情報やメモ (04/08)」 で紹介したように eval と value を使えば実現できなくはありません。 実際、「情報やメモ (04/08)」 で紹介した例も do for や while により if/reread を使わなくてもできるようになるのでだいぶ楽になるはずです。
(cf. 「情報やメモ (07/15 2011)」)
前回の報告 (04/22 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
相変わらず、win terminal への改良がジャンジャン入っています。 コンパイル環境の整備も進められていますが、 win terminal では、GDI+ によるアンチエイリアスの実装がなされました。 また、「情報やメモ (03/11 2011)」 で報告した極座標モードの中心の丸の問題も解決されています (fillstyle パターンの問題の修正)。 その他に、linetype 等に関するコードが大幅に修正されたおかげで、 solid, dashed などの terminal オプションも新設されましたし、 クラッシュする問題なども改良されています。
win terminal 以外の改良では、複素引数の asin() のバグ (asin(sin({1,1}))={1,-1} になるとか) の修正や、 readline の改良などが目につきます。
「splot notitle で等高線の key も削除するように」というのは、 前に報告した 「情報やメモ (03/11 2011)」 のパッチが採用されたものです。 しばらく音沙汰がなかったので不採用かと思ってたのですが、 全く唐突に実装されました。
上記以外に、新機能として「set [xy]label rotate parallel」 が実装されています。 具体例で紹介しましょう。 普通に splot すると、xlabel, ylabel は以下のようにつきます:
set xlabel 'これが X 軸'
set ylabel 'これが Y 軸'
splot sin(x+y)
見てわかる通り、軸のラベルは軸の方向とは無関係につきます。 現在は、xlabel に rotate オプションがありますので、 適宜回転させることも可能ですが、 それを自動的に軸に平行にさせるオプションが rotate parallel です:
set xlabel 'これが X 軸' rotate parallel
set ylabel 'これが Y 軸' rotate parallel
splot sin(x+y)
これは mouse によるドラッグで視方向を変えると、 ラベルの方向もちゃんとそれに追従してくれます。
なお、上の画像を見ると、 xlabel の方の角度がやや x 軸の方向とはずれているように見えます。 qt terminal, wxt terminal でも試してみたのですが、 それらでは特にずれているようには見えないので、 もしかすると x11 terminal のバグかもしれません。 時間のあるときに調べてみたいと思います。
2 ちゃんねるの掲示板「gnuplot を使おう。その 2」(アドレスは リンクリスト 参照) に書かれた情報について、多少気になるものがありましたので、 少し書いておきます。
だいぶ古い話だけど 512 番の記事の 「set polar の場合に軸に負の目盛りを打つには」 という方法がわかった、という報告がありました (884)。
それは rrange で負の範囲も指定することだ、 と書いてあったのですが、 実はそれは 512 番の記事の話とは内容が違います。 詳しくは、 「情報やメモ (01/08 2009)」 を参照してください。
けど、rrange で負の値が指定できるのはちょっと面白いです。
dgrid3d で格子データを作ると近似がうまくいかないのか z への寄与が x に比べて y が小さすぎて等高線がうまく書けない、 という質問がありました。 dgrid3d の後の数字 (rows, cols) を変えてみてもうまくいかないそうです (892)。
漠然とした質問であまり答えようがないのですが、 等高線は原理的に x と y のデータを同じスケールで扱って計算します。 よって、x と y のスケールが違うと妙な等高線ができがちです。 その場合、例えば「using 1:(5*$2):3」のようにして x と y のスケール変換をするとだいぶ感じが変わりますので、 試してみるといいかもしれません。
媒介変数モードの 2 つの曲線の描画 plot f(t), g(t), f(t), g(t)+h(t) でその 2 曲線間を塗り潰すには、という質問がありました (903)。
2 曲線間を塗り潰すには with filledcurve が使えるのですが、 残念ながら parametric モードには対応していません。 よって、完全ではありませんが、 疑似ファイル '+' を使ってデータ描画として with filledcurve を使えば一応はそのようなこともできます。 例えば以下のようなグラフでそれを説明します:
set parametric
set xrange [-1.5:1.5]
set yrange [-1.5:1.5]
plot sin(t),cos(t), sin(t),cos(t)+0.2*sin(6.0*t) lt 3
with filledcurve は、 3 列のデータの 2 番目、3 番目のデータを 2 つのグラフの y 座標とみて その間を塗り潰します。 よって、これを疑似ファイル '+' を使って描画するには、 以下のようにすればよさそうに見えます:
set samples 100
plot '+' using (sin($1)):(cos($1)):(cos($1)+0.2*sin(6.0*$1) notitle
with filledcurve
しかしこの場合、$1 の範囲 (xrange) はデフォルトの -10 から 10 までになってしまって グラフが中心に小さく表示されてしまいますが、 だからといって「set xrange [-1.5:1.5]」とすると、 グラフの横幅だけでなく、'+' データの $1 の範囲も -1.5 から 1.5 になってしまって、 そのためグラフ全体が描画されなくなってしまいます:
よって、set xrange はグラフの横幅を指定するのに使用し、 $1 には適切な範囲になるようにスケール変換して渡してやる必要があります:
set samples 100
xmin = -1.5
xmax = 1.5
set xrange [xmin:xmax] # グラフの横幅の指定
set yrange [-1.5:1.5]
tmin = 0.0 # $1 の範囲の最小値
tmax = 2.0*pi # $1 の範囲の最大値
x2t(x) = (x-xmin)*(tmax-tmin)/(xmax-xmin)+tmin
# x から t (=$1) へのスケール変換関数
plot '+' using (sin(x2t($1))):(cos(x2t($1))):(cos(x2t($1))
+0.2*sin(6.0*x2t($1))) not w filledcurve
さらに、demo/fillbetween.dem にあるように、 1 本目のグラフの方が大きい領域と 2 本目のグラフの方が大きい領域で 塗る色を変えたい場合は、
y1(t) = cos(t)
y2(t) = cos(t)+0.2*sin(6.0*t)
y3(t) = (y1(t)>y2(t))?y1(t):y2(t)
のようにして、一回目は「using (sin($1)):(y3($1)):(y1($1))」で描画し、
二回目は「using (sin($1)):(y3($1)):(y2($1))」で描画すれば
一応塗り分けられます:
ただし、このグラフは y 座標の大小で塗り分けをしていますが、 円 (y1 のグラフ) よりも内側か外側かで塗り分けるようにするには さらに工夫が必要になります。
前回の報告 (03/21 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
今回はわずか 1 ヶ月前からの報告なんですが、 一目でわかると思いますが、 最近は terminal への手の入り方が半端じゃありません。 特に win terminal と svg/canvas terminal への変更/改良は、 まるで競争 (B.Maerkisch vs E.Merritt) みたいになってました。 よくわかりませんが、それぞれいくつか機能が追加されているようです。 そのうち、win terminal のハーフトーンの改良は、 「情報やメモ (12/05 2009)」, 「情報やメモ (12/23 2009)」 で紹介したパッチのようなもののようです。
しかし今回の目玉は、「一般的な機能」で紹介しているものでしょう:
まず、最初のものから紹介します。 実は、これまでも「columnhead(2)」のような使い方はあり、 それによりデータの 1 行目にある文字列を key のタイトルに使えましたが、 これは文字列値関数ではなく、あくまで plot title のオプションでした。 よって、それで文字列を取得しても、 そのままそれを表示することしかできませんでした。
それが今回文字列値関数になりましたので、 表計算ソフトのデータのように 1 行目にデータの説明が簡単に書かれているような場合に、 その文字列を加工してタイトルを作ることができるようになりました。 簡単なサンプルを紹介します。
"国語","英語","数学"
70,30,80
50,40,30
20,20,40
set datafile separator ","
set xrange [-1:3]
set yrange [0:100]
set xtics ( "A さん" 0, "B さん" 1,
"C さん" 2 )
set pointsize 2
plot for [j=1:3] 'data.csv' using 0:j w lp
title columnhead(j)."の点数"
この例自体は、ドキュメントにあるものをほぼそのまま利用していて、 columnhead(j) の後ろに簡単な文字列 ("の点数") を追加しているだけですが、 gnuplot には他にも文字列処理関数がありますので、 それを利用すればもっと色々なことが可能になります。 多分そのような需要は多いと思いますので、 待望の機能と言っていいでしょう。
2 番目の with fillsteps は、steps の下のベースライン (x 軸) までの領域を、現在の fillstyle で塗り潰します。 どういうものを想定しているのかはよくわかりませんが、 with box のようなものです。上と同じデータのサンプルを一つ紹介します。
set datafile separator ","
set style fill pattern 2
set xrange [-1:3]
set yrange [0:100]
set xtics ( "A さん" 0, "B さん" 1,
"C さん" 2 )
plot 'data.csv' using 0:1 w fillsteps
title columnhead(j)."の点数 (1)" \
, '' using 0:1 w steps lt 3
title columnhead(j)."の点数 (2)"
比較のために steps のグラフを重ねて書いてみました。 pattern 2 としているのは、x11 の pattern 1 が何もしないためです。
最後の新しい機能 pm3d の rgb variable は多分大きい機能です。 これまでは splot の with pm3d による曲面の色付き描画の場合は、 そのグラフの z の値に応じた色づけをするか (3 列データ)、 4 列目にデータを追加してその 1 次元値を palette に投影した色を使用するしかありませんでした。 それが、rgb variable の指定によって、 4 列目の値を palette とも分離した自由な色を直接指定して塗り分けることが 可能になります。
例えばデータが 6 列あり、それぞれが (x,y,z,R,G,B) の値を表している場合 (R,G,B は 0≦R,G,B<256 の範囲)、
rgb(r,g,b) = 65536 * int(r) + 256 * int(g) + int(b)
splot 'data' using 1:2:3:(rgb($4,$5,$6)) with pm3d lc rgb variable
のようにすれば、palette とは無関係に色をグラフに塗ることができます。
一つ、疑似データ '++' を利用するサンプルを紹介します。
set samples 50
set isosamples 50
set xrange [-6:6]
set yrange [-6:6]
set view 30,30
set ztics ( -1, 0, 1 )
set title "パレットとは無関係に
x の値を緑に変換して塗るサンプル"
set xlabel "x 軸"
set ylabel "y 軸"
set cbrange [-1:1]
### 0≦R,G,B<256 の RGB 値を 24bit の RGB 整数に変換
rgb(R,G,B) = 65536 * int(R) + 256 * int(G) + int(B)
splot '++' using 1:2:(sin($1+$2)):(rgb(0,($1+6)*255/12,0)) \
with pm3d lc rgb variable notitle
グラフを見るとわかりますが、colorbar にない緑の色が曲面に塗られていて、 palette とは無関係の色が直接塗られていることがわかると思います。 なお、rgb() の引数の「($1+6)*255/12」は、 -6 から 6 までの x 座標の値を 0 から 255 の範囲に線形変換しているもので、 それを rgb() の緑の成分にのみ与えることで緑色階調にしています。
(cf. 「情報やメモ (05/23 2011)」)
gnuplot-beta ML の投稿を見て思い出しましたが、以前 「情報やメモ (01/15 2010)」、 「情報やメモ (09/21 2010)」 に、ファイルからデータを読み込んで、 それを変数 (配列) に保存してパラメータとして使う、 という例のようなものを紹介しました。
gnuplot に for 文があれば、 データを配列変数に保存して それを利用することもできるのでしょうが、 簡単にはいきません。 しかし、if と reread を使えば for 文に近いことが実現できるので、 それを使えばなんとかなります。 以下に簡単な例を紹介します。 ただし、以下に紹介するのはだいぶ無理矢理な方法なので、 当然 awk のように for を持つ言語の方から gnuplot を呼ぶ方が自然だと思います。
例えば、data1 の各行に、以下のように 1/n! の値が入っているとします:
1.000000000000000e+00この 1/n! の値を a_1, a_2, a_3, ... のような変数に保存するには、 まず以下のような gnuplot スクリプトを用意します (load1.gp):
5.000000000000000e-01
1.666666666666667e-01
4.166666666666667e-02
8.333333333333333e-03
1.388888888888889e-03
.....
j=j+1
eval sprintf("plot '%s' every ::%d::%d
using 0:(a_%d=column(1), 1) not",\
"$0", j-1, j-1, j)
if (j<$1) reread
eval を使っていますが、
それは変数名 a_j の j を実際の数値に展開するためです。
もし、そうしないと「a_j」という名前の変数に代入されてしまいますが、
実際にやりたいのは以下のような plot 列の実行です:
plot 'data1' every ::0::0 using 0:(a_1=column(1), 1) not
plot 'data1' every ::1::1 using 0:(a_2=column(1), 1) not
plot 'data1' every ::2::2 using 0:(a_3=column(1), 1) not
....
これにより、1 行目の 1 列目の値が a_1 に、2 行目 1 列目の値が a_2 に、
3 行目 1 列目の値が a_3 に、という具合に代入されていきます。
実際にはこの plot はダミーのプロットですので、出力は捨てる必要があり、
それには terminal unknown を利用すればいいでしょう。
$0 (call の最初のパラメータ) はデータファイル名、
$1 はデータを読み込む最後の行番号です。
このスクリプトを、 通常のメインの gnuplot スクリプトから以下のように call します:
set xrange [0:1] # dummy
set yrange [0:1] # dummy
set term unknown
Maxlines = 20
j = 0
call 'load1.gp' 'data1' Maxlines
これで、a_n (n=1,2,...,20) に 1/n! が代入されることになります。
これを利用して、sin(x) のテイラー展開のグラフを表示させると、
以下のようになります:
set xrange [0:1] # dummy
set yrange [0:1] # dummy
set term unknown
Maxlines = 20
j = 0
call 'load1.gp' 'data1' Maxlines
m = ceil(Maxlines/2)
f(x, n) = (n <= 1)? x*a_1 : \
f(x, n-1) + (-1)**(n-1)*x**(2*n-1)
*value(sprintf("a_%d",2*n-1))
set key out
set grid
set xrange [-10:10]
set yrange [-2:2]
set term x11
plot for [j=1:m] f(x, j) t sprintf("f(x, %2d)", j), sin(x)
f(x, n) は再帰定義関数で、(-1)n-1a_(2n-1)x2n-1 のような項の n=1,2,3,... の和になり、a_n = 1/n! ですから、 f(x, n) は sin(x) の n 項のテイラー展開となります。 a_n の値を使用するために value() と sprintf() を利用していますが、 a_3 のように具体的な n ならば直接使えるのですが、 変数 n に対して a_n を使う場合はこのようにしないと 「a_n」のような名前の変数を見てしまうことになります。
(cf. 「情報やメモ (06/23 2011)」)
最近の gnuplot は文字列変数も使えますし、 ある種の出力形式であれば、日本語もさほど指定せずに使えます。 奥村@三重大 さんが以下で公開しておられる 福島原発のデータでそのサンプルを示しましょう。
一番グラフ化が簡単そうなのは fukushima1MP.csv でしょうか。 以下のグラフは、CVS 版の gnuplot の x11 出力形式での例です。 X resource で
gnuplot*font: \のような設定をしていますので、 フォント等を特に指定せずに日本語が使えています。
mbfont:-misc-fixed-medium-r-normal--14-*-*-*-*-*--jisx0201.1976-0;\
-misc-fixed-medium-r-normal--14-*-*-*-*-*--jisx0208.1983-0
また、データは「nkf --unix | grep '^2011'」で前処理することで、 先頭についている文字列部分を除外しています。
set timefmt "%Y/%m/%d %H:%M"
set format x "%m/%d"
set xtics 60*60*24
set datafile separator ","
set xdata time
set title
"福島第一原子力発電所可搬型モニタリングポストによる計測状況"
jt1 = "事務本館南側 線量率"
jt2 = "正門 線量率"
jt3 = "西門 線量率"
set ylabel "(μSv/h)"
set grid
plot "data" using 1:($2*1000) w p t jt1,\
"" using 1:3 w p t jt2,\
"" using 1:4 w p t jt3
',' 区切りの CSV データは datafile separator で対応できます。 xtics の「60*60*24」は 1 日間隔を意味します。 jt1 等が文字列変数です。また、$2 だけマイクロではなくミリのようだったので、 1000 倍して単位を揃えてあります。 「with lines」でなく「with points」(w p) で書いていますが、 観測してないデータを線でつなぐのは気が引けたので w p にしました。
なお、この gnuplot スクリプトの内容は、 実際はシェルスクリプトのヒアドキュメントで書いていて、 nkf も grep も一つのスクリプト内に書いています。 ついでに wget も入れてデータの取得も書けば、 自動的なグラフ更新系が作れます。 その場合は $2 が別な意味に解釈されてしまうので、 column(2) に変更する必要があります。
もちろん、外部コマンドの方を gnuplot スクリプトの ! 行に書いて、gnuplot スクリプトだけで済ませる、という手もあります。
次は、各県毎のデータを可視化することを考えます。 データは mext-old.csv, mext.csv がありますが、 とりあえず全データではなく、 統計データの方の mext-old.csv の方を考えます。 日本地図のデータ、および地図上に色で塗り分ける手法は 「情報やメモ (03/26 2007)」 を参考にします。
「情報やメモ (03/26 2007)」 では、2 通りの方法を紹介していて、 gnuplot 4.2 以前用に awk で gnuplot スクリプトを生成させて それを load させる方法と、 gnuplot 4.3 以降用に plot for と system() 関数を使って gnuplot スクリプトだけで行う方法です。
ただ今回のデータの場合は、 いくつか (被災地の) 欠損データがあるようです。 そこは filledcurve で塗り分けることができず、 別のやり方で塗る必要があり plot for の手法が使えません。 よって、今回は awk による手法を紹介します。 そして、いっそ awk から gnuplot も実行することにして、 awk だけでやる方法を以下に示します。
「情報やメモ (03/26 2007)」 の地図データ japan_map.dat のデータは、 各県の枠線データが並んでいるのですが、 実はそのデータの県の並び順と、 上の mext-old.csv のデータの県の順番は同じものになっています。 よって、前の awk スクリプトとほぼ同じ方針でやればよいので、 それほど難しくはありません。 なお、fflush() を使っていますので、GNU awk が必要です。
BEGIN{
FS = ",";
if (k == "") k = 3;
map = "japan_map.dat";
tj = "環境放射能水準調査結果: ";
N = 47;
gnuplot = "gnuplot -persist";
print "unset key" | gnuplot;
print "unset border" | gnuplot;
print "unset xtics" | gnuplot;
print "unset ytics" | gnuplot;
print "set palette rgbformulae 33,13,10"
| gnuplot;
}
(NR == 3){ printf "set title \"%s%s\"\n",tj,$k
| gnuplot ; next }
($1 ~ /[0-9]/){ dat[$1] = $k }
END{
max = 0; for (j=1; j<=47; j++)
if (max < dat[j]) max = dat[j];
printf "set cbrange [0:%f]\n",max | gnuplot
for (j=1; j<=47; j++) {
if (j == 1) printf "plot \"%s\"",map | gnuplot;
else printf " \"\"" | gnuplot;
printf " index %d w filledc c notitle",j-1 | gnuplot;
if (dat[j] == "")
printf " lt rgb \"white\",\\\n" | gnuplot;
else printf " lt palette cb %f,\\\n",dat[j]+0 | gnuplot;
}
printf " \"\" w l notitle lt -1\n" | gnuplot;
fflush(gnuplot);
}
出力は、awk から gnuplot へパイプ出力を行っています。 MS-Windows の場合は、pgnuplot.exe か gnuplot.exe を使用してください。 上の awk スクリプトが sample.awk だとして、 これを実行するには、以下のようにします (Unix の場合):
nkf --unix mext-old.csv | awk -v k=8 sample.awk
上の awk スクリプトについて、簡単に説明します。 まず、BEGIN ブロック内の FS はデータセパレータの設定で、 CSV 形式用のものです。 「if (k == "") k = 3;」の部分の k は、 「k 列目をグラフ化」するための変数ですが、このようにしておくと、 awk の -v オプションで k を指定する場合のデフォルト値 (この場合は 3) を設定できます。
「(NR == 3)」の部分は、データの 3 行目に書かれている説明を取りだしていて、 それを「set title」でタイトルにしています。 データは 1 列目 ($1) が数値である場合 (県番号)、 それを一旦 dat[] という配列に保存しています。
END ブロックで、dat[] から最大値を求めて、それを cbrange の設定に使用し、 for 文で長い plot コマンドを出力しています。 この部分は実際には以下のような gnuplot コマンドを生成しています:
plot "japan_map.dat"
index 0 w filledc c notitle lt palette cb 0.030000,\
"" index 1 w filledc c notitle lt palette cb 0.021000,\
"" index 2 w filledc c notitle lt palette cb 0.051000,\
"" index 3 w filledc c notitle lt rgb "white",\
...
"" index 46 w filledc c notitle lt palette cb 0.022000,\
"" w l notitle lt -1
見てわかるように 1 県ずつ (index) filledcurves スタイルで
塗り潰しをしているのですが、
それを通常は litype palette cb で塗るのですが、
欠損データ (データがない) の場合は「linetype rgb "white"」で
白に塗り潰しをしています (index 3 は 4 番目の宮城県)。
最後に「"" w l notitle lt -1」で各県の枠線を黒で書いて終わりです。
fflush() でデータを強制的にプログラムに掃き出せば、
gnuplot が処理を実行してくれます。
動作がわかりにくい場合は「| gnuplot」を全部削除して、 出力される gnuplot スクリプトを確認するといいでしょう。
「情報やメモ (03/25 2011)」 で報告した enhanced モードで iconv が効かない問題の修正パッチですが、 それを Ethan Merritt さんが改善して CVS 版に採用してくれました。 テストしてみましたが、今度はいいようです。
「情報やメモ (03/21 2011)」 と 「情報やメモ (03/11 2011)」 で報告した、gd (png/gif/jpeg) ドライバで iconv を使って set encoding の設定に応じて日本語コード変換を行う機能の件ですが、 enhanced モードで、文字列に enhanced 文字列が入っている場合 (明示的に半角の ~,@,^,_,& が入っている場合か、 または「円」のように Shift_JIS 2 バイト目が たまたまこれらに一致してしまう場合) は、 iconv による変換を通らずに文字化けしてしまうことがわかりました。
例えば Shift_JIS 環境で ylabel として enhanced モードで「体重/身長^2」 などの文字列を使う場合に、 gd ライブラリがデフォルトでは UTF-8 を受けつけるようになっていると、 これは「set encoding sjis」としても iconv を通りませんので、 正しく表示されません。
以下のパッチでこの問題は修正されると思います。
本家にも送ってみましたが、採用されるかどうかはわかりません。
(cf. 「情報やメモ (03/27 2011)」)
前回の報告 (02/21 2011)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
見てわかる通り、win terminal への大量の修正、改良が入っています。 そのほとんどすべてが B.Maerkisch さんによるものです。 見た目の変更や機能の変更もあるようですが、 あまりに大量すぎて全然追いつけていけてません。 面白そうなものがあれば後で紹介したいと思います。
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
3D データの等高線の値を、key のところではなくて等高線のところに書きたい、 という質問がありました。
グラフ上に文字を書くのは set label でしか行えないのですが、 CVS 版の gnuplot ならば set label に for を使うことで ある程度は自動化できます。
ただ、むしろ問題なのは key のところに出るものを消す方です。 unset clabel で等高線に関する key の出力を消すことはできるのですが、 そうするとなぜか等高線が全部同じ線種で書かれてしまいます。 unset key だと曲面自身のタイトルも消えてしまいますし、 splot のコマンドラインで notitle とすると曲面のタイトルだけが消えて、 等高線の key は残ってしまいます。
つまり、等高線を別な線種にしつつ、key の曲面のタイトルは残して 等高線の方は消す、ということは現在はできないようになっています (multiplot の重ね書き、 あるいは曲面のタイトルを set label で手動生成しない限り)。
それを可能にするようなパッチを作ってみました (src/graph3d.c への差分)。
これを使うと、splot の notitle を使ったときは曲面のタイトルだけでなく、 等高線に関しても key への出力をなしにします (それが自然な気がします)。 これを使えば、以下のようにすれば等高線は別な線種として残しつつ、 曲面のタイトルは key に表示して等高線のものは削除する、 ということが可能になります:
set contour surface
splot 'data' w l nosurface notitle, '' w l nocontour
最初の描画では key も曲面もなしで等高線描画だけを行い、
次の描画で等高線なしの曲面描画を行っています。
ちなみにこれは本家にも送ってみたのですが、
今のところ採用はされていません。
なお、元記事の人は大量のグラフがあって手動では無理なので、 pm3d の色の濃さで表現する、という方式にしたそうです。 interpolate で滑らかにしたら、 最初は印刷結果がかなりあらかったそうですが (emf terminal)、 プリンタを変えたら綺麗に出たそうです。
(2406 の記事から始まるスレッド 「等高線の値を図の中に挿入したい」)
win terminal 上で、他の対話型出力形式で使えている mouse wheel が使えない、という問題が ML で話題になっていると 松岡さんから報告がありました。
後で kakuto さんからも問題の報告を頂きましたが、 無事他の出力形式同様に使えるようになりました (CVS 版)。 なお、この機能は現在の gnuplot-4.4.3 でも使えるようになっているようです (cf. 「情報やメモ (03/09 2011)」)。
(2412 の記事から始まるスレッド 「win terminal doesn't track mouse wheel?」)
gnuplot-4.4.2 の MS-Windows 環境で「円板を打ち抜く」 というタイトルをつけた eps ファイルを enhanced モードの postscript terminal でやると文字化けする、という質問がありました。
実は、これは Shift_JIS 2 バイト目の問題です (cf. 「情報やメモ (11/06 2004)」)。 MS-Windows では、普通に入力すると Shift_JIS という漢字コードになりますが、 日本語などの全角文字を表現する 2 バイトコードの 2 バイト目は、 文字によっては通常の半角英数字を表現する 1 バイト文字 (7 ビットコード) になる場合があります。 しかもそれが enhanced モードの特殊文字である '^', '_', '@', '&', '~'、 およびエスケープ文字である '\' のどれかに一致してしまうと、 gnuplot の enhanced モード処理である 1 バイトずつの処理に引っかかってしまい、 2 バイト文字が分断されて間違った特殊文字処理が行われてしまうわけです。 「円」は Shift_JIS では 2 byte 目が '~' と同じになっています。
とりあえず gnuplot-4.4.2 での回避策としては、以下のものが考えられます:
もし title が単に「円板を打ち抜く」でよいなら、 これは enhanced モードは必要ありませんので、 title だけ非 enhanced モードにして
set title '円板を打ち抜く' noenhanced font "..."
のようにする方法です。
しかし、title に上付きや下付きのような
enhanced モードが必要ならばそうはいきません。
その場合も enhanced モードが不要で、文字化けする文字だけ
set label noenhanced を使って書き分ける、という方法はあります。
この場合は、PostScript フォント名も 「GothicBBB-Medium-RKSJ-H」から「GothicBBB-Medium-UniJIS-UTF8-H」 のようなものに変える必要がありますし、 UTF-8 (BOM なし) が使えるエディタを利用する必要があります。
post terminal なら 8 進表記による文字コード指定の文字列も使えますので、 '円板' の代わりに '{\211\176}板' と書けば回避できます。
EPS ファイルはテキストファイルなので、エディタで修正する、 という手もあります。
最初のは簡単ですが、2 番目のも変なことを気にする必要のない対処法で、 実際質問した方は UTF-8 を利用するようにしたそうです。 ただし、エディタの設定でデフォルトでは BOM がついていたようですが、 それを外す設定をしたらうまくいったそうです。
さらにこの件に関して、以下のような話題が続きました。
上にも、あるいは 「情報やメモ (02/21 2011)」 にも書いたように、 現在の CVS 版では「set encoding sjis」が使えますので、 enhanced モードでの Shift_JIS 2 バイト目の問題はそれにより回避できます。 なお、後で kakuto さんや松岡さんから指摘されて気がついたのですが (2476 の記事から始まるスレッド 「emf enhanced での文字化け」 参照)、 この enhanced モードの問題の set encoding sjis による解消は postscript terminal に限りませんし、 さらに言えば、Shift_JIS 以外の 2 バイト (または 4 バイト) の文字コード全般に効果がありえます。 例えば、偶数バイト目が Shift_JIS 同様 7 ビット文字になってしまう GB18030 (中国), Johab (韓国), Big5 (台湾) などでも「set encoding sjis」で同じ問題が解決するのではないかと思います (もちろん、それらの利用者の間で問題になってたのかは知りませんが、 原理的には起こっていただろうことです)。
(2418 の記事から始まるスレッド 「日本語付き eps」)
松岡さんから win terminal の問題に関する 本家の ML の話題に関する情報提供がありました。
実はそれが丁度 SourceForge.net の CVS が落ちていた時期でもあった (SourceForge.net が 攻撃を受けたので、復旧まで多少時間がかかりました) ので、そこから、臨時に各自が持っている CVS 版のソースを公開するか、 という話になりました。 私も自分の手持ちのものを公開した (cf. 「情報やメモ (02/09 2011)」) のですが、 最終的には、別に git でソースツリーを公開しているサイトがあって、 そっちでもっと新しいものが手に入る、という情報が松岡さんから寄せられ、 そのうちに SourceForge.net もめでたく復旧しました。
(2444 の記事から始まるスレッド 「beta-ML windows terminal の周りのこと」)
最近、CVS 版で win terminal 用のヘルプの形式として、 従来の .hlp 形式のものに加えて HTML ヘルプ形式 (.chm) が追加導入されました。新しい MS-Windows (Vista 以後) では .hlp 形式は標準サポートではなくなっているので、 いいニュースでしょう。多分今後そちらが主流になるのでしょう。
それに関して、CVS 版での HTML ヘルプ形式の開発環境、 make したら図がうまく入らなかった、 MSVC++ 用の makefile がまだ対応していない、等の情報が、 MS-Windows 用 CVS 版バイナリを公開しておられる松岡さんや角藤さんから 寄せられました。 日本語マニュアルの .chm 形式のものも作ることができましたので、 現在公開しています。
なお、MS-Windows 用バイナリは、 make 時に .hlp を使うか .chm を使うかが決定されますので、 作成済みバイナリで両者を選択して使い分けることはできませんが、 .hlp 形式や .chm 形式のファイルは gnuplot なしでも単独で参照することはできるようです (参照するソフトが必要な場合もあります)。
(2454 の記事から始まるスレッド 「Windows HTML help」)
CVS 版の gnuplot では、
set polar
set rrange [2:7]
plot t
のように極座標モードで rrange の下の限界を正の値にすると、
中心に白丸が書かれるようになっていますが、
win terminal だとそれが黒丸になる、という問題があります。
実はこれは、win terminal の少し厄介な問題に起因しています。
現在、gnuplot では lt (linetype) で線種、lc (linecolor) で線の色が (指定できる terminal では) 別々に指定できるようになっているのですが、 昔は lt しかなかったため、線の色と点線の種類 (特に白黒モードの場合) を一つの lt で管理していました。 terminal ドライバのソースでも内部変数としてそれらは分離していなくて、 適宜場合分けなどを利用してその設定に対する処理が行われていたのですが、 現在は lc が導入されたことや、set object などで利用される 多角形内部のぬりつぶしなども実装されてきたため、 線の色と点線の種類を一つの変数で管理することが難しくなり、 多くの出力形式のドライバで線の色の指定と点線の種類の指定が 内部で分離されてきました。
しかし、現在の win terminal ではまだそれが行われておらず、 そのために従来、 mono モードでは point の境界が点線で描画されてしまう、 などの問題が起きていました。 この件もそれに起因しています。 実はこれをとりあえず解消する場当たり的なパッチもあります。
上記は両者が必要ですが、あくまで場当たり的なパッチで、
今回の問題は解決しても根本的な解決にはなっていません。
多分、他の出力形式同様、線の色と点線の種類を内部で分離して
ソースを書き直す必要があると思います。
本家にも送ってみたのですが、反応はいまいちでしたが、
分離すべきとの認識は持ってもらったみたいです。
# だからこれは採用はされてないし、そのうち誰かが頑張ってくれるでしょう (^^)
(2463 の記事から始まるスレッド 「set polar での win terminal の問題」)
いまや MS-Windows 用の公式バイナリを make しておられ、 本家の開発者 ML にも頻繁に顔を出しておられる松岡さんから、 いくつかの報告がありました。
なお、2472 番の記事で、 win terminal でアンチエイリアスが実装されたとも報告がありましたが、 これは擬似的なアンチエイリアスの実装で、 一度 2 倍の大きさのグラフを書いておいて、 それを元の大きさに縮小することで曲線を綺麗にする、 という仕組みのようです。
ダブルバッファリングによるアニメーションの平滑化、 テキストウィンドウの改良、fill transparent のサポート、 フォントに ClearType/Proof の選択を可能に (要 XP 以降)、 Windows HTML Help (.chm) の導入、ディレクトリのドラッグ/ドロップなど、 最近 win terminal に大きな改良が立て続けに入っているのですが、 松岡さんの報告 (2471 番の記事) にあるように、 それがほとんど B.Maerkisch さんによるものです。
なお、gnuplot-4.4.3 では、Windows HTML Help や set encoding sjis、 そして上の win terminal に関する一連の改良などは入っていません。
以前、MS-Windows 上の CVS 版バイナリの png terminal での日本語についてまとめました (cf. 「情報やメモ (01/25 2011)」)。 そこで、松岡版と角藤版のバイナリで、使用している gdlib の日本語対応が違っている (ライブラリ作成時のコンパイルフラグが違う) ので、松岡版では日本語は UTF-8、角藤版では Shift_JIS で与えないといけない、 と書きました。
Unix でも gdlib に関する状況は同じなのですが、 Unix の場合は、それをインストールする人が その Unix 環境の標準的なコードを知っていますから、 それなりに適切な環境を構築できますが、 MS-Windows の場合はバイナリ配布なので、 ダウンロードした個人ユーザが自分で環境を変えることはできず、 使用するバイナリの仕様に使用する漢字コードを合わせるしか ありませんでした。
しかも、gdlib には以下の仕組みがいずれもありません。
2 つ目のには近いものが入っています (Shift_JIS を EUC-JP に変換するとか、 EUC-JP を UTF-8 に変換するとか) が、 上に書いたもの自身は入っていません。 よって、gnuplot 側でコードを変換したりする方法もありませんでした。 しかし、最近以下のことに気がつきました。
このようにすれば、入力する文字列のコードに合わせて set encoding で適切なコードを指定すれば、両者で共通の書き方ができることになります。
ということで、そのようなパッチを作成してそれを報告したところ、 CVS 版バイナリの作成者である角藤さん、松岡さんから動作報告を頂きました。 角藤版では、既に現在のバイナリにはその仕組みが導入されているようで、 UTF-8 文字列も set encoding utf8 を指定すれば png terminal で出力できるようになっているようです。
やや日本ローカルな話題なのですが、 そのパッチを本家にも一応送りました。 意外にも反応は良く、丁寧に説明したところ、 ありがたいことに採用される方向で現在動いています。 なお、元は MS-Windows 環境用のパッチでしたが、 EUC-JP の Unix 環境でも害にはならなさそうです。
一旦 iconv ライブラリの利用が採用されれば、今後は gd.trm 以外、 あるいは日本語以外にも iconv の利用が広がっていく可能性も もしかするとあるかもしれません。
(2486 の記事から始まるスレッド 「gd.trm の iconv 対応」)
松岡さんから、このページの 「情報やメモ (03/03 2011)」 に書いた MS VC++ による static 版の make に関して 2 点意見を頂きました。
これはいずれも松岡さんの言われる通りなのですが、 まず C99 的なソースに関するパッチは実は昔本家に送ったことがありますが、 残念ながら採用はされませんでした。 私とほぼ同じパッチを taschna さんが本家の Patch Tracker に投稿した際のやりとりが以下にありますので、 それを見ると採用されなかった理由がわかります。
また、makefile.nt の方は、メンテナンスされていないのではなく、 手が入った上でコンソール版を pgnuplot.exe として作っているようだったので、 それを尊重しました。ただ、名前に関しては松岡さんの言われる通りで、 実際松岡さんが開発者の ML に報告し、開発者の一人である HBB さんが makefile.nt を修正してくださったようです。 そしてさらに MSVC++ 用の makefile.nt に対する HTML ヘルプに関する対応を含む改良も現在行われていて、 以前のものより多少すっきりした makefile に作り直されるようです (by B.Maerkisch)。
(2490 の記事から始まるスレッド 「竹のさんのgnuplot に関する情報やメモ(03/03 2011) について」)
「情報やメモ (02/21 2011)」 で、CVS 版に採用された「set encoding sjis」について書きましたが、 その最後の方に以下のように書きました:
なお、この問題は、postscript terminal の enhanced モードでの問題であり、 win terminal では問題はありませんし、 postscript terminal でも enhanced モードでなければ問題はありません。ところが良く考えると、enhanced モードに関してはこれは postscript terminal だけではなく、 例えば emf terminal などでも起こりうる問題でした。 それらに関しても set encoding sjis で実は解決しています ( gnuplot Q&A 掲示板 の、 2476 番の記事 (emf enhanced での文字化け) から始まるスレッド参照)。
gnuplot-4.4.3 が先日 (03/05) リリースされました。 配布物に含まれる NEWS には、以下のように書かれています。
gnuplot 4.4.3 での新しい機能、変更、修正
1 つ目のものは、 「情報やメモ (01/07 2011)」 にも書いた、CVS 版では実装されていた、 key の要素を n 行 m 列に配置するためのオプションです。
2 つ目のものは、文字列変数等が導入されている関係で あると便利なものかもしれません。
emf 出力形式への変更は、 「情報やメモ (02/21 2011)」 でも紹介した、 CVS 版への更新などが入っているようです。
なお、日本語マニュアル、MS-Windows 用の日本語化キットは、 既に公開 しています。
(cf. 「情報やメモ (03/11 2011)」)
最近下に書いたものについて外部から意見を頂きました。 それについて書いておきます。
「情報やメモ (01/25 2011)」 に、MS-Windows 上の 2 種類の CVS 版の gnuplot の png/gif/jpeg terminal (gd ドライバ) に関する情報を書きましたが、 これに関して角藤さんから連絡が来ました。 それによると、角藤版は以下のようになっている、 あるいは修正するそうです。
最後の条件が満たされていれば、
set title "テスト" font "MSMINCHO,20"
でちゃんと出るようになるそうです。
実際、今回頂いた報告の後に更新された角藤版バイナリを うちの環境 (W32TeX は入ってない) でテストしてみたところ、 cmd.exe が立ち上がってしまう問題は起きませんし、 msmincho.ttc で GDFONTPATH の設定なしでちゃんと日本語が出ました。 ただ、W32TeX は入ってないので、fontconfig 系のフォント指定 (font "MSMINCHO,20") は効きません。
また、03/06 2011 に更新されたものでテストしたのですが、 gnuplot Q&A 掲示板 の、 2486 番の記事 (gd.trm の iconv 対応) で報告した iconv 対応が組込まれているようで、 UTF-8 エンコードのスクリプトでも
set term png
set out "test1.png"
set encoding utf8
set title "テスト" font "msmincho.ttc,20"
plot x
set out
のように「set encoding utf8」の指定をすれば文字化けせず
正しく出力されるようになっているようです。
なお、この iconv 対応の話については、後でまとめたいと思います。
角藤さん、どうもありがとうございました。
「情報やメモ (03/03 2011)」 に書いた、MS-Windows 上の MSVC++ での CVS 版の gnuplot のコンパイルの話について、 gnuplot Q&A 掲示板 の、 2490 番の記事 (竹のさんのgnuplot に関する情報やメモ(03/03 2011) について) で松岡さんから意見を頂きました。 特に、MS VC++ 用の makefile (config/makefile.nt) の問題について、 gnuplot の開発チームのメーリングリストで報告して頂いたようで、 03/05 2011 の開発版で config/makefile.nt に関する改良が入りました。 HTML Help に関する改良はまだ入ってませんが、$(O) の定義がないとか、 コンパイルフラグの問題とか、 コンソール版の gnuplot の名前が pgnuplot.exe になっていたとか、 コンソール版の gnuplot のコンパイルフラグに /subsystem:windows がついているとか、その辺の問題はすべて修正されています。
松岡さん、どうもありがとうございました。
このページは、主に備忘録代わりに、 または何らかの検索で飛んでくる人はいるかもしらんなぁ程度に書いていて、 順番もでたらめ (思いつき順) ですし、 順に見ていくには適さない形式なんで 更新したのがすぐに見られるなんてことはないだろうと思っていたのですが、 今回の報告を通じて、 「うっ、意外に見られてるやん、少なくとも内容はちゃんと書かな」 と感じた次第です <(_ _)>
今回、ある事情で、 CVS 版の gnuplot を MS-Windows 上で *.dll なしで使えるように (wgnuplot.exe)、とコンパイル作業してみました。 色々と苦労しましたので、備忘録としてここにまとめておきます。 なお、コンパイルに使用したのは Microsoft Visual C++ 2005 Express version (以下 VC++) です。
VC++ で gnuplot をコンパイルする場合は、 config/makefile.nt を使って、src ディレクトリで
nmake -f ..\config\makefile.nt
のようにするのですが、
一部のソースには VC++ には通らない (C99 的な)
書き方が使われているので、まずそこを修正する必要があります。
具体的には構造体の初期設定の部分で、詳細は以下のパッチをご覧ください。
また、VC++ 2005 では makefile.nt も修正が必要です。 最近導入された、HTML Help (.chm) 形式への対応差分と合わせたものを 以下に紹介します。
中にはバグ ($(O) の定義がない) の部分もありますが、 多くは HTML Help 形式に対応した修正です。 コンパイルフラグは、/G5 /GX をやめて /EHsc にして、 /MD を /MT にしていますが、 前者はコンパイラが出す警告にしたがったもので、 後者は .dll を使わないためのものです。 /MD だと msvcr80.dll が必要になる可能性があるようです。 また、現在では標準的な /DEAM_OBJECTS も追加してあります。
config/makefile.nt は、この他にもライブラリに関する変更がありますが、 それについては後で説明します。
gd ライブラリのコンパイル済みバイナリ、 および PDF ライブラリのコンパイル済みバイナリをまず使ってみたのですが、 PDF ライブラリは基本的に .dll が必要なもののようですし、 gd ライブラリの .dll 不要な static ライブラリ bgd_a.lib の方も、 リンク時にエラーが大量に出ました。
それに gd ライブラリは、 デフォルトでは日本語は UTF-8 文字列のみを受けつけるので、 /DJISX0208 をつけて Shift_JIS 対応版にしたかったので、 gd ライブラリのソースからのコンパイルをやることにしました。 そのためには、最低限 zlib, libpng, libjpeg, freetype2 のライブラリが必要です。 それぞれ、コンパイル済みバイナリもあり、 以下の説明のようにすればそれらを利用してコンパイルができるのですが、 残念ながら static ライブラリの方はこれではうまくいきません (gnuplot にコンパイルで使えるものができません)。
ということで、zlib, libpng, libjpeg, freetype2 もそれぞれソースからコンパイルすることにしました。 いずれも static ライブラリを作ります。
まずは zlib からですが、zlib-1.2.5 を利用しました。 make は、展開した zlib-1.2.5 のディレクトリに入って行います:
cd zlib-1.2.5
nmake -f win32\Makefile.msc OBJA=inffast.obj zlib.lib
なお、win32\Makefile.msc の CFLAGS の -MD を -MT に、
LDFLAGS の -debug を削除していますし、
OBJA の指定が必要なことに注意してください
(Makefile.msc の OBJA= の行を OBJA=inffast.obj と書いてもいい)
コンパイルが終わったら、zlib-1.2.5 があるのと同じディレクトリに requires というディレクトリを作って、 必要なヘッダーファイルとライブラリファイルをコピーしておきます:
mkdir ..\requires
copy zconf.h zlib.h zlib.lib ..\requires
cd ..
libpng は libpng-1.2.24 を利用しました。 しかし、libpng は VC++ でのコンパイルは、projects\ 以下のプロジェクト環境しか用意されておらず、makefile がありません。 よって、zlib の Makefile を参考に、 以下のような適当な makefile を書いてコンパイルしました:
zlib を使いますので、CFLAGS に zlib のパス ..\\zlib-1.2.5 が書いてありますが、これは ..\\requires に書き換えてもいいでしょう。 これで以下のようにすれば結構です:
cd libpng-1.2.24
nmake -f ..\makefile-libpng-1
copy pngconf.h png.h libpng.lib ..\requires
cd ..
libjpeg は、v6b (jpegsrc.v6b.tar.gz) を使用しました。 makefile は VC++ 用の Makefile.vc があり、修正も必要ないので、 単に以下のようにするだけです:
cd jpeb-6b
nmake -f Makefile.vc libjpeg.lib
copy j*.h libjpeg.lib ..\requires
cd ..
freetype ライブラリは、freetype-2.3.5 を利用しました。 ドキュメントを見ると、これは nmake ではコンパイルできないようで、 GNU make が必要なようでしたので、 以下にある MS-Windows 用のコンパイル済みの GNU make バイナリを利用しました。
その上で、freetype-2.3.5\docs\INSTALL.GNU にあるように、
make setup visual
make
としてコンパイルしました。
makefile は、自動的に多数の makefile を読み込む形式になのですが、
freetype-2.3.5\builds\compiler\visualc.mk の
「CFLAGS ?= /nologo /c /Ox /G5 /W3 /WX」を
「CFLAGS ?= /nologo /c /Ox /W3」に変えてコンパイルしました。
なお、/WX を取らないと、警告で止まってしまってコンパイルが進みません。
コンパイル後に、objs に作られるライブラリとヘッダーファイルをコピーします:
xcopy /s include ..\requires
copy objs\freetype.lib ..\requires
cd ..
さていよいよ gdlib です。gdlib は 2.0.35 を利用しましたが、 2.0.36RC1 や開発版を利用する方がいいかもしれません。 今回は、fontconfig は使用しないものを作りたかったので、 2.0.35 でほぼ用事は足ります。
gd は VC++ 用の makefile が gd-2.0.35\windows\Makefile として用意してありますので、これを使います。 gd-2.0.35 に関しては、以下の個人的な改良パッチ (文字の回転と Symbol フォント等のエンコーディング) も当てています (詳細は、 「情報やメモ (03/08 2005)」, 「情報やメモ (12/15 2007)」 参照)。
makefile である gd-2.0.35\windows\Makefile は、 requires\ のファイルを参照する、JISX02028 の定義、 static ライブラリ用のリンクライブラリの変更、 コンパイルフラグの変更、make ターゲットの変更等の修正を行っています:
コンパイルフラグは、/DNONDLL が必要なようです。 もしかしたら、コンパイル済みバイナリである gdlib の static ライブラリ bgd_a.dll はそれをつけずにコンパイルしてあるのかもしれません。 また、通常の Makefile では static ライブラリには freetype, zlib, jpeg, libpng 等のライブラリを リンクするようにはなっていませんので、そちらが原因かもしれません。
このパッチを当てた後、windows\ ディレクトリで nmake を実行すれば OK です:
cd gd-2.0.35\windows
nmake
copy ..\gd*.h bgd_a.lib ..\..\requires
cd ..\..
いよいよ wgnuplot です。config/makefile.nt は、 上の msvc-make-1.diff を当てた後で以下のものを当てています:
やっているのは、gd ライブラリとヘッダーファイルの置き場所の指定、 PDF ライブラリの無効化、gd ライブラリの static 指定 (/DNONDLL, bgd.dll を bgd_a.dll に差し替え)、pgnuplot, wgnuplot_pipes のコンパイル/リンクオプションの修正、 新しい wgnuplot 用の修正等です。
pgnuplot は、gnuplot-4.4 から config/makefile.nt がだいぶ書き換えられて、 console 版の gnuplot をコンパイルするようになっているのですが、 /subsystem:windows がついているためにリンクがうまくいきません。 多分バグだと思いますがそれを修正してあります。
このパッチを当てた後で、src\ に移動して nmake を実行します:
cd src
nmake -f ..\config\makefile.nt default
これで src ディレクトリに static 版の
wgnuplot.exe, gnuplot.exe, wgnuplot_pipes.exe ができます。
さらに、新しい HTML Help 形式の wgnuplot.chm
ファイル (英語版) もできていると思います。
日本語版の .chm ファイルの作成についてはまたいずれ書きたいと思います。
(cf. 「情報やメモ (01/15 2015)」)
「情報やメモ (02/21 2011)」 で報告した CVS 版の更新情報の中に、 極座標関係のものと boxplot に関するものがいくつか含まれています。 極座標に関する大きな改良は昨年 11 月頃に行われていますし、 boxplot は昨年 1 月頃に CVS 版に新たに導入された描画スタイルですので、 それらについて少し紹介しておきます。
まず極座標に関する改良ですが、 12/06 2010 の報告 と 先日 (02/21 2011) の報告 をからそれらを抜き出すと以下のようになります:
この中で最も大きな変更は、さらっと書いていますが実は 11/18 2010 の変更です。 さらに詳しく見ると (ChangeLog)、以下のように書いてあります。
さらに、極座標に関する付属ドキュメントの主要な変更部分も以下にあげます。
これらを見ても多少その様子がわかると思いますが、 以下にグラフの例を紹介します。可能なものについては、 以前の版 (version 4.4.1) との比較で示しますが、 いずれも x11 terminal での出力を画面キャプチャしたものです。
CVS 版の出力には動径軸が表示されることがわかります。 デフォルトで set raxis になっているので、 unset raxis で以前のグラフと同じになります。
set polar
plot t # らせん
CVS 版の出力には、上の「set raxis」に書かれているように 白丸が表示されます。 また、xrange, yrange の自動縮尺も rrange の設定に合わせて変更されていることがわかります。 以前はグラフ全体が合うようになっていましたが、 CVS 版では原点を中心に左右上下対称に取られていることがわかります。 極座標ではむしろこちらの方が自然だろうと思います。
set polar
set rrange [2:7]
set trange [2:7]
plot t
set rtics で raxis に目盛りをつけられます。 表記は通常の xtics と同じです。 mirror によって左側にも見出しをつけられます。
set polar
set rtics mirror pi
plot t
set log r とすると動径方向が対数軸になるので CVS 版ではグラフの形、x の範囲、y の範囲が変わりますが、 x 軸、y 軸は線形軸のままです。 しかし、以前の版ではグラフが変わりません。 多分、以前の版では r のスケール変換と x, y のスケール変換が同期していて、 そのために見た目が変わらないのではないかと思います。
set polar
set log r
set rrange [1:7]
set trange [1:7]
plot t
x11 terminal では、グラフ描画時にグラフウィンドウ上で 1/2 のキーを押すと座標の描画モードが変わります (builtin-{decrement/increment}-mousemode)。 詳しくは、bind コマンドを実行してください。 CVS 版では、その中に極座標表示が含まれていて、 「polar: [ラジアン] [動径座標]」のように表示されます。 下のグラフは、マウスカーソルが グラフの左端のほぼ縦軸 0 の位置にあるようなグラフで、 角度がほぼπ、動径座標がほぼ 4.0 位になっています。
set polar
plot t
なお、set polar での r=r(t) のグラフは、 基本的に次のような式に基づいて描かれます:
x=r(t)*cos(t)これは r(t) が負の場合にも「有効」なようで、 よって例えば r(t) が負の場合は、
y=r(t)*sin(t)
x=r(t)*cos(t) = |r(t)|*cos(t+π)となって、原点からの距離がその絶対値で、 角度は 180度 (=πラジアン) 回転させたような場所に表示することになります。 例えば以下のグラフを見ればそれがわかります:
y=r(t)*sin(t) = |r(t)|*sin(t+π)
set polar
set trange [-1:1]
plot t
原点より左側にあるのが [-1:0] の r(=t) に対応した部分で、 本来はそのときの角度 [-1:0] は右下 ([-π/2:0]) にあるのですが、 それがπだけ足された左上 ([π/2:π]) に表示されています。 これが式としては連続しているので、グラフもつながって表示されるわけです。 なお、これは CVS 版でも以前の gnuplot でも同じです。
よって、逆に r(t) が正のデータのみグラフに描かせたい場合は、 以下の posf() のような関数をかぶせてクリッピングする必要があります:
posf(x) = (x>=0)? x:1/0 # 正だけ取り出す
negf(x) = (x<=0)? x:1/0 # 負だけ取り出す
set polar
set trange [-1:1]
plot posf(t), negf(t)
データファイルの場合には、 using 指定で「using 1:(posf($2))」のようにします。 さらに set rrange を指定している場合は、より奇妙な感じになります:
set polar
set rrange [2:7]
plot t
実は、この白丸の下から左の方に伸びている部分は、 本来は r<2 の範囲の部分のグラフです。 しかし、rrange [0:*] でも r が負の部分をクリッピングしないのと同様、 この r<2 の部分もクリッピングしません。 set rrange [rmin:rmax] が指定された場合は、
x=(r(t)-rmin)*cos(t)に基づいて描画されているようで、以下のようにするとそれがわかります。
y=(r(t)-rmax)*sin(t)
upperf(x,m) = (x>=m)? x:1/0 # x>m だけ取り出す
lowerf(x,m) = (x<=m)? x:1/0 # x<m だけ取り出す
set polar
set trange [0:7]
set rrange [2:7]
plot upperf(t,2), lowerf(t,2)
次は boxplot について紹介します。 boxplot の付属ドキュメントを参照してみましょう:
まず、例をお見せしましょう。boxplot は、値の統計的な分布を表現する一般的な方法です。 四分位境界は、1/4 の点が第一四分位境界以下の値を持つように、 1/2 の点が第二四分位境界 (メジアン) 以下の値を持つように、 等と決定されます。 第一四分位と第三四分位の間の領域を囲むように箱を描画し、 メジアン値のところには水平線を描きます。 箱ひげは、箱からユーザ指定限界まで延長されます。 それらの限界の外にある点は、ひとつひとつ描画されます。
例: (省略)
その箱のデフォルトの幅は `set boxwidth [width]` で設定できますが、 plot コマンドの `using` による 3 番目のオプション列でも指定できます。 1 番目と 3 番目の列 (x 座標と幅) は通常データ列ではなく定数として与えます。
デフォルトでは、箱ひげは箱の端から、 y の値が四分位範囲の 1.5 倍の中に収まっていて 最も離れているような点まで延長されます。 デフォルトでは、範囲外の点 (outlier) は円 (pointtype 7) で描かれます。 箱ひげの端の棒の幅は `set bars` を使って制御できます。
1 7
2 2
3 1
4 9
5 8
6 10
7 15
8 11
set grid
set style fill solid border -1 # 箱をベタ塗り、境界線は黒
set pointsize 3 # 除外点 (outliner) 用
plot 'data' using (0):($2) with boxplot
横は x = 0 を中心に描かれていますが、これは using (0) の部分です。 真ん中の箱の横幅には特に意味はありません。意味があるのは縦です。 グラフを見ると、箱は y=4.5 から y=10.5 まで書かれていて、 y=8.5 のところに水平線があります。 さらに、ひげが、y=1 から y=15 まで伸びています。
データの 2 列目 ($2) を見ればわかるように、 このひげはデータの最小値と最大値を意味しています。 そして箱ですが、これはデータの「1/4 値、1/2 値 (中央値)、3/4 値」 を表しています。中央値は「メジアン」とも呼ばれます。 このデータの場合、$2 データをソートすると「1,2,7,8,9,10,11,15」(8 個) となりますから、中央値は y=8 と y=9 の間、よって y=8.5 が 1/2 値、 1/4 値は 2 番目 (y=2) と 3 番目 (y=7) の間、よって y=4.5 が 1/4 値、 3/4 値は 6 番目 (y=10) と 7 番目 (y=11) の間、よって y=10.5 が 3/4 値、 ということになります。 この 1/4 値、1/2 値、3/4 値を箱と水平線で表しているわけです。
より詳しく言えば、次のようにしているようです:
しかし、とびぬけている点がある場合は、それは outlier (除外点) とみなされ、別に点で描画されます。例えば上のデータ点のうち、 「7 15」を「7 20」に変えると次のようなグラフになります。
y=20 のところに outlier が、 set pointsize 3 のために大きい点で表示されています。 グラフのスケールが違っているのでわかりにくいですが、 除外点を除いて 1/4 値等を計算し直しているわけではなく、 除外点までひげを伸ばすのをやめているだけのようです。 set ytics 1 にして grid を見ると箱部分の値が変わっていないのがわかります。
計算し直しているなら 7 点になるので、1/4 値と 3/4 値は p[2]=2 と p[6]=10 になるはずですがそうはなっていません。
除外点は、yrange や candlestick のような追加列で指定するものではなく、 データから自動計算されるようで、ドキュメントにある通り 「四分位範囲の 1.5 倍の中に収まって」いるかどうかで分かれるようです。 上の例の場合には、1/4 値、3/4 値は 4.5 と 10.5 ですから四分位範囲の幅は 6.0、 その 1.5 倍は 9.0 なので、-4.5 から 19.5 まではひげを伸ばしますが、 それを越えるとそれは除外点と見なすようです。 実際、データが 19 にしてもひげが伸びますが、 19.5 を越えると伸びなくなります。
前回の報告 (12/06 2010)以後、 現在の CVS 版に入れられた主な機能について紹介します (ChangeLog, manual の更新部分等より)。
また少し報告の間が空いて、2 月半位経ってしまいました。 この間、色々な修正が入っています。特筆すべきものなどを抜きだすと、 以下のような感じでしょうか。
上記の多くは、 gnuplot Q&A 掲示板 での議論発の修正です。 最近は、松岡さんがかなり積極的に gnuplot の開発側に関わっているため、 そのような流れになっていると感じています。 日本の gnuplot ユーザにとっては大きなことかと思います。
set encoding sjis は、postscript terminal の enhanced モードの場合の、 以下の Shift_JIS コードの 2 バイト目の問題に対応したものです。
ほぼ 6 年越しの問題だったわけですが、 現在の set encoding の仕組みで解消できることに気がついて (というか set encoding utf8 で似たような回避をしていたことに気がついた)、 今回めでたく採用、となったわけです。 これで、wgnuplot のような Shift_JIS 環境でも、 2 byte 目が '\' や '^', '~' などの漢字でも問題なく使えるようになります。
set term post enh
set out 'file.ps'
set title '能^2' font 'GothicBBB-Medium-RKSJ-H,20'
set xlabel '蛙雲機十円' font 'Ryumin-Light-RKSJ-H,20'
plot x
set out
「能」、「十」は 2byte 目が '\' (5Ch), 「蛙」は '^' (5Eh)、
「雲」は '_' (5Fh)、「機」は '@' (40h)、「円」は '~' (7Eh) で、
いずれも enhanced モード特殊文字とぶつかりますので、
Shift_JIS 環境では一つとして満足には出ないものばかりです。
これが、3 行目に「set encoding sjis」あるいは「set encoding locale」
を入れることで、いずれも正しい日本語が表示されるようになります。
なお、この問題は、postscript terminal の enhanced モードでの問題であり、
win terminal では問題はありませんし、
postscript terminal でも enhanced モードでなければ問題はありません。
なお、2byte 目が '\' の漢字を、上の例のような一重引用符「'」ではなく、 二重引用符「"」で囲んだ場合は、そのような漢字の後ろに '\' をおぎなって、
set title "能\^2" font 'GothicBBB-Medium-RKSJ-H,20'
set xlabel "蛙雲機十\円" font 'Ryumin-Light-RKSJ-H,20'
のようにする必要があります。
(cf. 「情報やメモ (02/23 2011)」, 「情報やメモ (03/09 2011)」, 「情報やメモ (03/09 2011; no.2)」, 「情報やメモ (03/11 2011)」, 「情報やメモ (03/21 2011)」)
最近 (1 月の終わり頃) 、Sourceforge.net が攻撃を受けたために、 サービスを停止して復旧が行われています。 そのため、gnuplot も CVS 版のダウンロードが行えなくなっています。
卒論の時期でもありますし、 そのための実害もそろそろ出てくるのではないかと思いますので、 緊急非難的に、私が持っている CVS ソースをアーカイブしたものを 一時以下に置いておきます。 CVS ソースと同じ prepare 前のものですから、 prepare してからコンパイルしてください。
(cf. 「情報やメモ (03/11 2011)」)
MS-Windows 上の png terminal について、備忘録として書いておきます。 現在、MS-Windows 用の gnuplot-4.5 (CVS 版) バイナリは 以下の 2 種類があります:
これらは、コンパイル環境も違いますが (前者は MS VC++、後者は MinGW)、 リンクしているライブラリも違います。 今回、png terminal (gdlib) で日本語タイトルを出そうとして 少しとまどいましたので、その違いをまとめておきます。 なお、以下の話は「png terminal」限定の話です。 試すのは、以下のようなコマンド列です:
set term png
set out "test1.png"
set title "テスト" font "MSMINCHO,20"
#set title "テスト" font "msmincho.ttc,20"
plot x
set out
set GDFONTPATH=C:\WINDOWS\FONTSこれを設定しておかないと、set term png のとき、および plot の際に 多重に cmd.exe が起動するような現象が起きて、fontconfig のエラー (fontconfig: Could't retrieve font file name) が出る。
MS-Windows では png terminal を使う必要性は それほど多くないかもしれませんが、 一応上げておきます。
gnuplot Q&A 掲示板 での見聞き等で得た情報を備忘録として書いておきます。
松岡さんから gnuplot-4.4.2 のリリースの報告がありました。 4.4.2 は、 「情報やメモ (09/28 2010)」 にも書いたように 4.4.1 のリリース直後に出て、 2,3 のバグの修正が行われたものです。
(2337 の記事から始まるスレッド 「4.4.2のリリース」)
MS-Windows アプリケーションの DLL の読み込みについて、 セキュリティ上の脆弱性の指摘を見つけました。 wgnuplot に関して質問してみたところ、 松岡さんから詳しい調査報告等がありました。 とりあえず MS-Windows XP SP3 なら問題はないようです。
(2339 の記事から始まるスレッド 「DLL の読み込み」)
key の要素を n 行 m 列の形に配置する場合、 その行数と列数の指定がうまくいかない、という質問がありました。 具体的には、要素が 9 つある場合に、
set key outside top horizontalとしてグラフの上に並べる際、 3 行 3 列になってしまうのを 2 行 5 列にして横幅を一杯に使いたいが、 set key のオプションで maxrows 2 としてもうまくいかない、 ということでした (gnuplot-4.5 の wgnuplot)。
元記事の方は、描画順序を入れかえたら表示できた、 ということでしたが (詳しいことはよくわかりません)、 確かに
set key top outside horizontal maxcols 10 maxrows 2では win term では 3x3 になってしまいます。 調べてみると以下のような状況のようでした。
plot for [i=0:8] (x-i)**2
上の 3 番目に書いたのが具体的な列数、行数の決定ルーチンですが (vertical の場合は列数と行数が逆になる)、 列数上限は x11 terminal では 5、win terminal では 4 なので、 9 つの要素を納める最小行数は x11, win では それぞれ 2, 3 と計算されます。 そして 9 つの要素を納めるための列数の再計算 (なるべく少ない列数を使おうとする) により列数がそれぞれ 5, 3 となるので、 結果として x11, win でそれぞれ 2x5, 3x3 となります。
だから、win では 3 列しか横に並べられないわけではなく、 実際はデフォルトで 4 列まで横に並べることができます。 例えば 8 つの要素の場合は win terminal でも 2x4 になります。 しかし、9 つの要素の場合は上のような列数の再計算によって 4 列にはならずに 3x3 となっています。 よって、逆に 9 つの要素の場合は、2x5, 3x3 にはできますが、 3x4 にすることはできない、ということになります。
この辺りは、自動計算に加えてユーザ側でもそれを変更できるように した方がいいように思いますが、難しいところかもしれません。
(2342 の記事から始まるスレッド 「keyの行数と列数」)
松岡さんから、gnuplot と OpenOffice などを組み合わせた 利用法に関する文書を書いたとの報告がありましたが、 それに関して emf terminal、win terminal に関する議論になりました (かっこ内の番号は記事番号)。
さらにこれら 3 つの点に関して議論が続きました。 まず 1 番目の「中塗りの記号」に関しては、
といった感じになりました。 2 つ目の「四角の大きさ」に関しては、
といった感じになりました。 3 つ目のものに関しては、
といった感じでした。最初の 2 つは結局 CVS 版にも反映されたので、 それなりに有意義な議論であったと思います。
なお、1 つ目のものは、emf terminal のヘルプには書かれていないので、 今のところは gnuplot の隠しオプションになっています (^^)
(2355 の記事から始まるスレッド 「gnuplot, OpenOffice 等のフリーウェアを使ってプレゼン用や論文用のグラフを作成する」)
松岡さんから、gnuplot で作成した漢字入りの emf ファイルを OpenOffice で取り込む (インポートする) と OpenOffice がクラッシュする、 という報告がありました。 wgnuplot は日本語に関しては Shift_JIS の emf ファイルを作成するのですが、 OpenOffice は UTF-16 の emf ファイルにしか対応していないそうです (MS-Office は Shift_JIS の emf も OK)。
gnuplot 側で set encoding によって、 Shift_JIS を UTF-16 に変換するような作業を考えておられたそうですが、 OpenOffice フォーラムの方で、 Shift_JIS の emf ファイルを UTF-16 の emf ファイルに変換するフィルタを 作って公開してくれた方がおられたそうです。 現在は、松岡さんのページ http://www.tatsuromatsuoka.com/gnuplot/Jpn/gnuplot_memo.html#101218 でも配布されています (2391 の記事 「OpenOffice用emf ファイルの日本語文字コード変換プログラム」)。
さらにその議論の中で、win terminal の白黒モード (set term win mono) の場合に、点種の輪郭が点線になってしまうという 古いバグが残っていることが報告されましたが、 それもなんとか解決することができて (ついでに別なバグも修正された)、 これも本家の CVS 版に反映されました。
(2373 の記事から始まるスレッド 「emf terminal, windows terminalなどについて」)
昨年の年末に、この掲示板の運営管理者でもある松田@東京電機大 さんの「Octave の精義」(カットシステム) が出版されました。 理工系の学生や研究者向けのなかなか素晴しい本ですが、 その中で gnuplot との相性について言及している部分が気になり、 それを質問してみました。
これに関して、著者の松田さん、および Octave に非常に詳しい松岡さんから 回答がありました。 1 つ目の「PostScript 出力の横幅」の問題に関しては、
といった話でした。まあ敢えて octave 側で手を入れているなら、 または開発版で解消されているなら、 gnuplot の方で何らかの対処をする必要は少なくともなさそうです。
2 つ目の「デフォルト terminal」の問題に関しては、
という話でした。これも gnuplot 側でどうこうという話ではないようです。 これ以外にも、以下のような話もありました。
私もちょっと Octave に触ってみたくなりました。
(2393 の記事から始まるスレッド 「Octave との相性」)