「gnuplot」カテゴリーアーカイブ

論文に使える図をgnuplotで作る

本稿の目的は、論文に用いることができるレベルの図をgnuplotで制作することです。
gnuplotはVersion 5.2 patchlevel 8を利用しています。

方針


本稿の方針としては、実際の論文からとってきた図を再現することです。
元データはないので、あくまで枠線や、フォントなどを合わせることを目的とします。

対象とする図は以下の[1]の図3と[2]の図3にします。
これらを選んだ理由は特にないですが、これらを再現することを目標にします。

[1]の図3を再現


ではまず、Phys. Rev. A 102, 033316 (2020)の図3を再現しましょう。

[1]の図3

[1]の図3をgnuplotで再現した図

gnuplotで用いた全コードは以下に折りたたんでおきます。

データは適当に作成しました。データのダウンロードは以下からどうぞ。
https://slpr.sakura.ne.jp/qp/supplement_data/PRA102_033107_Fig3likedata.tar.gz

細かな説明をしていきます。

  • 線の色の指定
    線の色はlinetypeで決定していきます。

    set linetype  1 lc rgb '#0072bd' lw 1 # blue

    の意味は、gnuplotでプロットした時の1番目の線を、カラーコード’#0072bd’, 線の太さ”1″とすることを指定しています。プロット時に”lc 1″としてもこの1番目の色に変更できるようになります。linetype 6まで同じです。

  • 複数画面の表示位置指定
    続いて、

    # left top figure(1) position
    lx1=0.14; ly1=0.87
    rx1=0.47; ry1=0.57

    ~~~

    set lmargin screen lx1
    set tmargin screen ly1
    set rmargin screen rx1
    set bmargin screen ry1

    の部分について説明します。個別画面の左上の座標\((lx1, ly1)\)と右下の座標\((rx1, ry1)\)を決定します。座標の原点は全体の左下\((0,0)\), 全体の右上\((1,1)\)としたときに決められます。実際にその値を適用しているのがlmargin, tmarginなどです。詳しい説明は、gnuplotで複数の図を載せるを参照してください。

  • eps出力のためのターミナル指定
  • if(@ARG1 == 1){
      set terminal postscript eps size 5,5 dashed enhanced color font 'Roman,20'
      set output "PRA102_033107_Fig3.eps"
    }

    の部分は、出力ターミナルの設定を行っています。条件分岐は引数によってターミナルに出力するのか、epsとして画像出力するのかを指定するためです。使いやすさのためです。重要なのは、 size 5,5 の箇所です。ここを正方形にしておかないとxyの比が変わってしまうので扱いづらくなります。
    eps画像の切り抜き(Boundary boxの変更)はgsviewなどでできるので、画面四方の空白はいくらあってもよいです。そのサイズをgnuplot上で合わせるよりも、gnuplotで思った通りの出力をすること優先しましょう。
    フォントも重要ですね。経験上、2×2の画像であればsize5,5の時フォントサイズ20よいと思います。論文の本文はRomanフォントが使われるため、図もRomanにしておいたほうがよいでしょう。

  • 個別画面の細かい指定
    1. タイトルの指定
      set title "{/Gothic-bold=24 Linear scale}" offset 0,0

      タイトルを指定します。図のLinear scaleと書かれた太字です。[1]の図を見ると、どうもゴシック体の太字で書いているようです。なので、フォントをGothic-boldとして、文字の大きさを24に変更します。

    2. 凡例の指定
    3. set key reverse samplen 1 width 0

      凡例はkeyで指定します。reverseは凡例の中の”文字-線の種類”の表示順を”線の種類-文字”に変更します。samplenは、凡例内の線の長さを変更する(デフォルトで4)、wigthは線の種類と文字の間隔を指定するパラメータとして考えればよいでしょう。具体的な値は実際に出力させて何度も気に入るまでトライアンドエラーしています。

    4. x,y軸の設定
    5. unset log x
      set xr[-2:52]
      set xtics 10 nomirror
      set mxtics 1
      set format x "%2.0f"
      set xl "{/Roman-Italic {/=20 tJ}}/{/=14 @^{/Symbol=14 -}{/Roman-Italic {/=20 h}}}"

      軸設定をまとめて説明しますが、特に特殊文字の出力が難しいと思うのでここに注目します。プランク定数は特殊文字であり、postscriptターミナルでは出力することができないと思います。なので、文字hとハイフンを組み合わせて出力しています。私が思いついたわけではなくググりました。[4]に詳細が書いてありまして、それから持ってきました。文字サイズが違うので適当に合わせました。
      y軸も同じですので、省略します

    6. グラフのプロット
    7. plot "hJ5_fit.d" u 1:2 w l lw 2 lc 5 dashtype 2 ti "{/Gothic-Condensed linear fit}",\
           "hJ5.d" u 1:2 w l lw 2 lc 1 dashtype 1 ti "{/Roman-Italic M}=24   ",\
           "hJ5.d" u 1:2 w l lw 2 lc 2 dashtype 2 ti "{/Roman-Italic M}=32   ",\
           "hJ5.d" u 1:2 w l lw 2 lc 3 dashtype 4 ti "{/Roman-Italic M}=64   ",\
           "hJ5.d" u 1:2 w l lw 2 lc 4 dashtype 3 ti "{/Roman-Italic M}=128 ",\
           "hJ5.d" u 1:2 w l lw 2 lc 5 dashtype 5 ti "{/Roman-Italic M}=256 "

      最後にグラフをプロットします。dashtypeは実線、破線を決定するパラメータです。私の環境では実線が1, 破線は2以降になっていますが、環境によって違うかもしれません。各自合わせましょう。
      また、linear fitという文字は、なんというかギュッとまとまっています。しかもRoman体ではなくゴシック体です。これを指定するには、

      ti "{/Gothic-Condensed linear fit}"

      と入力することで実現可能です。

以上でおおよその説明が終わりです。

重要なのはトライアンドエラーです。ターミナルによって表示が異なるので、postscriptで出力すると決めたら確認はpostscriptで行いましょう。実際に最終出力図をqtターミナルの表示上では、このようになります。

ベクタ形式であるEPS画像のサイズは102.5kBです。論文に投稿する場合でも許容できるサイズではないでしょうか。

ラスタライズ形式であるPNGをimagemagickを用いて

convert -density 400x400 -background white -flatten -alpha off PRA102_033316_Fig3.eps PRA102_033316_Fig3.png

で変換すると、91.8kBです。この程度の差であれば、ベクタ形式のほうが良いでしょう。

[2]の図3を再現


続いてPhys. Rev. A 102, 033107 (2020)の図3を再現しましょう。
大きな違いはカラーマップを利用した図であることです。

[2]の図3

[2]の図3をgnuplotで再現した図

データは適当に作成しました。データのダウンロードは以下からどうぞ。
https://slpr.sakura.ne.jp/qp/supplement_data/PRA102_033107_Fig3likedata.tar.gz

※ギリシャ文字Φは、

{/Symbol-Oblique f}

とすることでギリシャ文字のイタリックを用いることができます。

[1]と同じ部分がかなりあるので、違う部分だけを説明していきます。

  • カラーマップの設定
    見た目で[3]の’hot’と呼ばれるカラーセットだとわかったので、それを用います。

    set palette rgb 21,22,23 negative # colormap setting

    ただし、カラーマップの色が反対になっているので、それを指定するnegativeを追加しています。

  • カラーボックスの設定
    unset colorbox

    ~~~~

    set cbtics 0.5 scale 0 # scale 0, to delete tics line in colorbox
    set cbr[-2:0]
    set colorbox user origin 0.91,0.35 size 0.02,0.25 border # change size of colorbox

    カラーボックスに注目すると、左図(a)はカラーボックスがないですが、右図(b)にはあります。なので、カラーボックスを出力しないunset colorboxを指定しています。
    また、(b)のカラーボックスはカラーの値を示すところにticsが入ってないため、cbticsのscale(ticsの線の大きさ)を0にしています。
    さらに見ると、カラーボックスの大きさが少し小さいです。なので、カラーボックスの大きさ位置を指定するために、set colorbox user origin …を指定しています。

  • テキストボックスの表示
    set label tc rgb "black" at graph 0.02, graph 0.95 front "(a)"

    グラフ上のテキスト(a), (b)は、テキストボックスを追加して画面上に表示します。上のような指定で表示できます。

ベクタ形式であるEPS画像のサイズは752kBです。論文に投稿する画像としては、許容できるといえばできるサイズですが、若干大きいです。

ラスタライズ形式であるPNGをimagemagickを用いて

convert -density 400x400 -background white -flatten -alpha off PRA102_033107_Fig3.eps PRA102_033107_Fig3.png

で変換すると296kBです。2倍少し容量が小さくなるので論文全体の画像数が多いのならば、ラスタライズ形式の方が良いかもしれません。共著者と相談するとよいでしょう。

以上で説明を終わります。

参考文献


[1]S. Goto and I. Danshita, “Measurement-induced transitions of the entanglement scaling law in ultracold gases with controllable dissipation”, Phys. Rev. A 102, 033316 (2020)

[2]Z. Chen and F. He, “Interference of nuclear wave packets carrying different angular momenta in the dissociation of H2+ in strong circularly polarized laser pulses”, Phys. Rev. A 102, 033107 (2020)

[3]color mapについて
http://www.gnuplotting.org/?s=color

[4]6.4 What if I need h-bar (Planck’s constant)? -gnuplot FAQ
http://www.gnuplot.info/faq/#x1-610006.4

そのほか有用なページ

gnuplotでoption詰め込んで論文用figureを作ってみた[1] -qiita, @ucc_white
https://qiita.com/ucc_white/items/544b85e009a58d046d3c

Gnuplotのいろは -東京工業大学 科学技術創成研究院 佐藤千明研究室
http://www.csato.pi.titech.ac.jp/From2014/software/how-to-gnuplot.html

gnuplot上で行う任意関数のフィッティング

gnuplotには、”fit”というコマンドがあります。
これを利用すると、データ列に対して、任意の自由度を含んだ関数\(f(x)\)でフィッティングを行うことが出来ます。
手法はMarquardt-Levenberg法に基づいた非線形最小二乗法によるフィッティングです。

gnuplot ver4.6の場合

データ列”data.d”を\(f(x)=ax^2+bx+c\)でフィッティングする\(a,b,c\)を求めたい場合、gnuplot上で

f(x)=ax**2+bx+c
fit f(x) "data.d" u 1:2 via a,b,c

※gnuplot ver5.0以降の場合、エラーバーで重みづけしたフィッティングが出来るようです。
http://gnuplot.sourceforge.net/demo_5.0/fit.html

説明


以下のデータ列(ファイル名”data.d”)に対してgnuplot上でフィッティングを行います。

データは、関数
\(
\displaystyle f(x)=\frac{1}{1+e^{x-15}}
\)

に乱数を与えて生成したデータです。

このデータ列に対して、
\(
\displaystyle f(x)=\frac{a}{1+e^{(x-b)/c}}
\)

でフィッティングを行い、未知の定数\(a,b,c\)を決めたいと思います。

gnuplot上で

f(x)=a/(1+exp((x-b)/c))
a=1e0
b=10e0
c=0.5e0
fit f(x) "data.d" u 1:2 via a,b,c

と打つと、\(a,b,c\)にフィッティングした後の定数が入ります。
ここで、フィッティング前に\(a,b,c\)の値を入れているのは初期値です。
初期値があまりにも違うとうまくフィッティングが失敗するので、出来るだけ近い値を入れましょう。

実際に動かすと

> fit f(x) "data.d" u 1:2 via a,b,c
...

Final set of parameters            Asymptotic Standard Error
=======================            ==========================

a               = 0.995618         +/- 0.005679     (0.5704%)
b               = 15.3268          +/- 0.051        (0.3327%)
c               = 0.970465         +/- 0.04439      (4.574%)

...
>

という文章が出力されます。

フィッティングの結果、
\(a=0.995618,b=15.3268,c=0.970465\)と求められました。
乱数を与える前のデータは\(a=1,b=15,c=1\)ですので、元の関数に近いことが分かります。
fitコマンドを動かした後は既に\(a,b,c\)に値が代入されているので、そのまま

plot f(x)

とすれば、フィッティング結果をプロットすることが出来ます。

データと共に載せれば以下のようになります。

フィッティングする範囲を制限したければ、

fit [10:20] f(x) "data.d" u 1:2 via a,b,c

とすると、\(x\)の範囲を\([10,20]\)に制限することが出来ます。

2変数関数のフィッティング


2変数関数であろうとフィッティングは可能です。
元のデータ
(https://slpr.sakura.ne.jp/qp/supplement_data/data2.d)
は、関数
\(
g(x,y)=x\sin(xy+0.5)
\)

に適当な乱数を足して作られたデータです。グラフにすれば

となります。

このデータに対して、gnuplot上で関数
\(
g(x,y)=ax\sin(bxy+c)
\)

によるフィッティングを行います。コマンドは

g(x,y)=a*x*sin(b*x*y+c)
a=1.3e0
b=0.7e0
c=0.3e0
fit g(x,y) "data2.d" u 1:2:3 via a,b,c

です。
実行すると

>fit g(x,y) "data2.d" u 1:2:3 via a,b,c

...
Final set of parameters            Asymptotic Standard Error
=======================            ==========================

a               = 1.16313          +/- 0.004072     (0.3501%)
b               = 1.00073          +/- 0.001672     (0.1671%)
c               = 0.495134         +/- 0.003432     (0.6932%)
...

>

と得られますので、フィッティング結果と共にプロットすれば

となります。

初期値が答えに割と近いですが、これは失敗を防ぐためです。全ての初期値のパラメータを0で行った所失敗しました。

参考サイト


Gnuplotでの関数fitting
gnuplot demo script: fit.dem -ver5.0
gnuplot demo script: fit.dem -ver4.6
Fit (manual)
gnuplot で最小二乗フィッティングする -ゴルディアスの涙目

gnuplotで、あるディレクトリ内にある全てのファイルをプロットする

まとめ


gnuplotで、ディレクトリ(dat)内にある全てのファイルをプロットするには、

fnames=system("/bin/ls ./dat/*")
plot for[fn in fnames] sprintf("%s",fn) u 1:2

とすればいいです。

状況


いま、ディレクトリの構造が

.
└── dat
    ├── a.d
    ├── b.d
    └── c.txt

となっているとします。ここで、datはプロットしたいデータ(a.d、b.dとc.txt)が入っているディレクトリです。
この時、gnuplot上で

fnames=system("/bin/ls ./dat/*")
plot for[fn in fnames] sprintf("%s",fn) u 1:2

と入力すれば、ディレクトリdat内にある全てのファイルがプロットされます。

また、拡張子.dにあてはまるものだけをプロットしたければ、

fnames=system("/bin/ls ./dat/*.d")
plot for[fn in fnames] sprintf("%s",fn) u 1:2

とすればいいです。

gnuplotで平均と分散を表示する

gnuplotで平均、分散を表示します。
このページのゴールは↑のアイキャッチ画像を得ることを目的にします。

持ってるもの

・ファイル名”qwerty.d”に格納された1列目x、2列目y(x)のデータ。

gnuplotを用いて出力するもの

・平均、分散の表示

コマンド
stats "qwerty.d" u 1:2 name "qw" nooutput

plot "qwerty.d" u 1:2 pt 7 ps 1,\
      qw_mean_y lw 3 lt 1 lc 1 notitle,\
      qw_mean_y+qw_stddev_y lt 2 lc 1 notitle,\
      qw_mean_y-qw_stddev_y lt 2 lc 1 notitle

とすれば以下の画像が得られます。

真ん中の黒い実線が平均値、上下の黒の点線は平均値±標準偏差を表します。
データが正規分布に従うのであれば、真値(この場合は平均値=真値を仮定)を中心に約68%が上下の点線内に入ります。

gnuplotで複数の図を載せる

gnuplotで複数の図を載せたい時はmultiplotを使います。

うまくmultiplotを使いこなすポイントは、
・1つ1つの図の上下左右の絶対位置を指定する
・eps画像のサイズを決定する
・トライ&エラー
です。

multiplotとは


multiplotとは、その名の通り複数の図を同時にgnuplot上で表示させることです。
これを使うと、図同士の比較が出来たり、insetを入れることが出来るようになります。

さて、gnuplotには標準で横2行×縦3列など決まったレイアウトのmultiplotが出来る

set multiplot layout 2,3

というコマンドが存在しますが、ここではlayoutは使いません。
なぜなら、グラフの細かい調整が出来ないからです。例えば、2つの図でx軸を共有させたい場合がありますがこれはlayoutを使うと出来ません。なので、これに頼らない方法を紹介します。

2枚の図を同時に表示させたいとします。
この時、2枚の図の位置を、

set lmargin screen 0.3
set rmargin screen 0.9
set tmargin screen 0.9
set bmargin screen 0.7

のように指定します。lmarginなどは↓の図位置の長さを指定しています。

座標は絶対位置で、左下を座標(x,y)=(0,0)にとり、右上を(x,y)=(1,1)として考えます。

座標(1,1)は出力形式で設定したサイズを表しています。
例えば、サイズを横3インチ、縦5インチに設定した場合、座標(0.5,0.5)は横1.5インチ、縦2.5インチの座標を表しています。

これは重要なことです。
今、完成した画像を完全な正方形のグラフにしたいとします。
この時、座標を縦横0.5のサイズを持つようにとったとしても、出力形式のサイズが正方形でない限り完成した図が正方形になることはないことを意味しています。

x軸を共有したい場合


x軸を共有したい場合、
1枚目の画像(青線)のbmargin

2枚目の画像(緑線)のtmargin
を一致させ、lmarginとrmarginを一致させると良いでしょう。
この場合↓の図のように考えます。

実例がこちら。

コードの中身はこんな感じ。

清書

上の図を少し綺麗にしてみました。
書式やticsは引き継がれるので、各々のplotの前にできる限り記述をしたほうが良いでしょう。

縦軸と横軸を共通に


縦軸と横軸を共通にしたい場合はこんな感じにとれば良いです。

実例

コードの中身はこんな感じ。

insetを入れる


注意する点は、2番目のグラフが1番目のグラフの上に来る、ということです。

また、insetは背景を白くするために白色のオブジェクト

set object 1 rect behind from screen 0.3,0.2 to screen 0.6,0.5 fc rgb "#ffffff" fillstyle solid 1.0

を入れています。デフォルトでは透過してしまうためです。

Note


アイキャッチのフォントは “Commune-Round”を用いています。 http://www.gebsite.org/

幾何学模様(gnuplot)

gnuplotで幾何学模様を描きます。

正多角形の組み合わせで幾何学模様を描きます。
gnuplot version5.0以上でないと動きません。

用いるのは正多角形の数式
\(
\begin{equation}
\left\{
\begin{aligned}
x&\displaystyle =\cos t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}\\
y&\displaystyle =\sin t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}
\end{aligned}
\right.
\end{equation}
\)
です。ここで、\(a_n=\frac{2\pi}{n}\)、\({\rm floor}(x)\)は床関数(床関数と天井関数)であり、媒介変数\(t\)の範囲は(\(0\le t \lt 2\pi\))です。

正六角形を特に考えましょう。以下のスクリプトを実行することで

set param
set xr[-5:5]
set yr[-5:5]
set tr[0:2*pi]
unset key
set size ratio -1

n=6
# +---polygon---+
s1(x)=x-floor(x)
a(n)=2e0*pi/real(n)
cnp(n,t)=cos(a(n)*s1(t/a(n))-0.5e0*a(n))
pc(n,t)=cos(t)*cos(0.5e0*a(n))/cnp(n,t)
ps(n,t)=sin(t)*cos(0.5e0*a(n))/cnp(n,t)
set samples n*3+1

# +--- geometric pattern ---+
nr=1e0
ix=6
jy=6
xc=0e0
yc=0e0
xr=1e0
yr=sqrt(3e0)
oddshift=0e0
   
plot for[i=-ix:ix]for[j=-jy:jy] \
nr*pc(n,t)+xr*i+xc,\
((i+ix)%2 == 1 ? nr*ps(n,t)+yr*j+oddshift+yc : nr*ps(n,t)+yr*j+yc) lc 1

geoex_c
という画像が得られます。
これは、正六角形の組み合わせで作られており、それを格子状に配置することで幾何学模様を作り出しています。

格子点の配置や正六角形の大きさを変更することで様々な幾何学模様が得られます。
上記スクリプトの変数はそれぞれ
————————-
nr : 正n角形の大きさ(比率)
jx : 格子の列数の半分
jy : 格子の行数の半分
xc : x方向の格子のオフセット
yc : y方向の格子のオフセット
xr : x方向の格子の間隔
yr : y方向の格子の間隔
oddshift : x方向の奇数番目の列に対するy方向のオフセット
————————-
以下はxr,yr,oddshiftの組み合わせによって得られる様々な幾何学模様のパターンです。
geometric0_c
グラフェンっぽいのができますね。
3次元に簡単に拡張できるので、炭素の構造とかも作れます。

もちろん回転させることも可能です。
その場合はスクリプト”setting pattern”以下を

# +--- setting pattern ---+
nr=1e0
ix=6
jy=6
xc=0e0
yc=0e0
xr=1e0
yr=1e0

oddshift=yr/2e0
theta=pi/2e0

plot for[i=-ix:ix]for[j=-jy:jy] \
((i+ix)%2 == 1 ? pc(n,t)*cos(theta)-ps(n,t)*sin(theta)+xr*i+xc : pc(n,t)+xr*i+xc),\
((i+ix)%2 == 1 ? pc(n,t)*sin(theta)+ps(n,t)*cos(theta)+yr*j+yc+oddshift : ps(n,t)+yr*j+yc) lc 1

と変更してください。これは奇数列目のみを回転させる操作です。
適当なパラメータにおいて、
geo6rot_c
という模様が得られます。

また、正n角形全てのパターンを考える事が出来ます。例えば、正七角形の場合、
geo7rot_c
といった模様が得られます。

線とグラデーション(gnuplot)

gnuplotで、線の色を少し変化させながら色を付けていきます。

複数の線をグラデーション


 set linetype  1 lc rgb "#ff0000" lw 1
 set linetype  2 lc rgb "#ff1f1f" lw 1
 set linetype  3 lc rgb "#ff3f3f" lw 1
 set linetype  4 lc rgb "#ff5f5f" lw 1
 set linetype  5 lc rgb "#ff7f7f" lw 1
 set linetype  6 lc rgb "#ff9f9f" lw 1
 set linetype  7 lc rgb "#ffbfbf" lw 1
 set linetype  8 lc rgb "#ffdfdf" lw 1

 set linetype  9 lc rgb "#0000ff" lw 1
 set linetype 10 lc rgb "#1f1fff" lw 1
 set linetype 11 lc rgb "#3f3fff" lw 1
 set linetype 12 lc rgb "#5f5fff" lw 1
 set linetype 13 lc rgb "#7f7fff" lw 1
 set linetype 14 lc rgb "#9f9fff" lw 1
 set linetype 15 lc rgb "#bfbfff" lw 1
 set linetype 16 lc rgb "#dfdfff" lw 1

plot for[i=1:8] 0.2*i*x w l lw 2 lc i lt 1 title sprintf("%d",i)
replot for[i=9:16] -0.2*(i-8)*x w l lw 2 lc i lt 1 title sprintf("%d",i)

を実行すると、
lineg_c
という画像を得ます。

1つの線をグラデーション


set table "d1.d"
plot x
unset table

set table "d2.d"
splot "d1.d" u 1:2:2
unset table

plot "d2.d" u 1:2:3 w l lw 4 lc palette

を実行すると、
line_gra_c
と言うグラフが得られます。縦軸の値に応じた色で付けられます。

gnuplotで点にラベルを付けて出力

gnuplotで点とその点の値を付けたいとします。
数点だけならば、

set label "moji" at 4,0.2

とやれば点(4,0.2)に”moji”という文章が書かれます。

複数点の場合を考えます。
ここでは、データ”test.d”として、

1 0.1
2 0.2
3 0.3
4 0.4
5 0.5
6 0.6
7 0.7

を考えます。gnuplot単体でやることはできないと思います。
若干作業しなければなりません。

ファイル”test.plt”を生成し、中に以下の文を書きます。

unset label

!perl -ane 'print "set label sprintf(\"\%6.4f\",$F[1]) at $F[0]-0.05,$F[1]+0.04\n"' test.d > p.plt

load "p.plt"
plot "test.d" pt 7

とすると各点の位置からx軸方向に-0.05, y軸方向に+0.04ずれた位置にその点のy軸の値が出力されます。gnuplot上で上のファイルを読み込むと以下の出力を得ます。
point_label

参考文献
Basic statistics with gnuplot

gnuplotである1つの点のみを表示する

gnuplotで複数行から成るデータの第n行目だけを点としてプロットしたい場合があります。

例えば、全100行から成るデータ(“data.d”)の第17行目だけをプロットしたいとします。
この時、

plot "data.d" every ::17:0:17:0 u 1:2

とすれば、第17行目だけが点としてプロットされます。

その他、例えばデータではなく、ある関数のf(x)のx=5.7の時だけの値をプロットしたい時は

plot sprintf("< echo ''%f %f''", 5.7,f(5.7))

とすればよいです。

例1

データ”test.d”として

1 0.1
2 0.2
3 0.3
4 0.4
5 0.5
6 0.6
7 0.7

を考えます。この時gnuplot上で、

plot "test.d" every ::5:0:5:0 pt 7

と行うと
pointevery
というグラフが得られます。

例2

sin(5.7)を考えます。gnuplot上で

plot sprintf("< echo ''%f %f''", 5.7,sin(5.7)) pt 7

とすれば
point_function
という画像を得ます。都合上同時にsin(x)も出力しています。

参考文献
 複数のデータファイルのある列の差分表示 -計算機は楽し
gnuplotのコマンドまとめ(ループとかeveryとか) -Linux, Mac, Emacsについての設定、覚え書き

正多角形とスピログラフの数式

正多角形とスピログラフの数式です。

  1. 正多角形(2次元)
  2. 正多角形(3次元)
  3. 星型多角形(2次元)
  4. 星型多角形(3次元)
  5. トロコイド(2次元)
  6. トロコイド(3次元)
  7. スピログラフ

2016/10/24
幾何学模様を作りたい方は幾何学模様(gnuplot)へどうぞ。


スポンサーリンク


正多角形の式(2次元)


正n角形の数式は[1]を参考に修正しました。
正n角形の数式は、
\(
\begin{equation}
\left\{
\begin{aligned}
x&\displaystyle =\cos t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}\\
y&\displaystyle =\sin t \cdot \frac{\cos \frac{a_n}{2}}{\cos\left[a_n\left\{\frac{t}{a_n}-{\rm floor}\left(\frac{t}{a_n}\right)\right\}-\frac{a_n}{2}\right]}
\end{aligned}
\right.
\end{equation}
\)
です。ここで、\(a_n=\frac{2\pi}{n}\)と置きました。また、\({\rm floor}(x)\)は床関数(床関数と天井関数)を表します。
媒介変数\(t\)の範囲は(\(0\le t \lt 2\pi\))です。
グラフを書かせてみますとこうなります。

polygon3_10_c
n=3,4,5,6
n=7,8,9,10の順で、単位円を一緒に記述しています。
線の色の濃さは媒介変数の値に応じて変化させています。

gnuplotのスクリプトはこちら

多面体の式(3次元)


半径1の多面体は、平面のx,yの媒介変数による正n角形の関数をそれぞれpc(t),ps(t)と置くと、
\(
\begin{equation}
\left\{
\begin{aligned}
x& = {\rm ps}(u)\cdot {\rm pc}(v) \\
y& = {\rm ps}(u)\cdot {\rm ps}(v) \\
z& = {\rm pc}(u)
\end{aligned}
\right.
\end{equation}
\)
と書けます。
媒介変数\(u,v\)の範囲は(\(0\le u \lt \pi, \;\; 0\le v \lt 2\pi\))です。

プロットすると以下のようになります。
polygon3d_3_10_c
n=3,4,5,6
n=7,8,9,10の順です。

gnuplotスクリプトはこちら

星型多角形(2次元)


\(
\begin{equation}
\left\{
\begin{aligned}
x&\displaystyle =\cos t \cdot \frac{\cos a_n}{\cos\left[a_n -\frac{1}{n}\cos^{-1}\{\cos(nt)\}\right]}\\
y&\displaystyle =\sin t \cdot \frac{\cos a_n}{\cos\left[a_n -\frac{1}{n}\cos^{-1}\{\cos(nt)\}\right]}
\end{aligned}
\right.
\end{equation}
\)
です(\(n\ge 5\))。ここで、\(a_n=\frac{2\pi}{n}\)と置きました。
グラフを書かせてみるとこのようになります。
starpolygonp_c

gnuplotスクリプトはこちら。
※\(\cos^{-1}(\cos(x))\)は不安定です。
場合により書けなくなることがあります。ここでは上記関数の代わりに、正弦波ではない周期関数の数式
で記述した関数\(s(a,x)\)を用いています。

星型多角形(3次元)


3次元の場合は多面体の時と同じように、平面のx,yの媒介変数による星型多角形の関数をそれぞれstpc(t),stps(t)と置くと、
\(
\begin{equation}
\left\{
\begin{aligned}
x& = {\rm stps}(u)\cdot {\rm stpc}(v) \\
y& = {\rm stps}(u)\cdot {\rm stps}(v) \\
z& = {\rm stpc}(u)
\end{aligned}
\right.
\end{equation}
\)
と書けます。
媒介変数\(u,v\)の範囲は(\(0\le u \lt \pi, \;\; 0\le v \lt 2\pi\))です。
グラフはこのようになります。
starpolygon3dp_c

gnuplotスクリプトはこちら。

トロコイド(2次元)


トロコイドと呼ばれる曲線があります[2]。
これをgnuplotで書いてみましょう。数式は[2]を参考にして以下の通りです。
\(
\begin{equation}
\left\{
\begin{aligned}
x& = \left[(n-1)\cos t +h\cos((n-1)t)\right]/n \\
y& = \left[(n-1)\sin t +h\sin((n-1)t)\right]/n
\end{aligned}
\right.
\end{equation}
\)
\(h=1\)の時、半径が1の円に内接するように決めています。
また、\(n\)が整数の時、内接する円が外側の円をちょうど一周回った時に元の位置に戻る条件です。
別に整数でなくても構いません。その時はもっと複雑なものになることでしょう。

書いてみますと曲線はこうなります。
自由度\(h\)を1にしてグラフを書いてみましょう。
trocoid2d_3_10_c

自由度hを少し変えてみましょう。
trocoid2dh_3_10_c

トロコイド(3次元)


3次元の場合は多面体の時と同じように、平面のx,yの媒介変数によるトロコイドの関数をそれぞれhcyc(t),hcys(t)と置くと、
\(
\begin{equation}
\left\{
\begin{aligned}
x& = {\rm hcys}(u)\cdot {\rm hcyc}(v) \\
y& = {\rm hcys}(u)\cdot {\rm hcys}(v) \\
z& = {\rm hcyc}(u)
\end{aligned}
\right.
\end{equation}
\)
と書けます。
媒介変数\(u,v\)の範囲は(\(0\le u \lt \pi, \;\; 0\le v \lt 2\pi\))です。

trocoid3d_3_10_c
n=3,4,5,6
n=7,8,9,10の順です。

gnuplotスクリプトはこちら

スポンサーリンク

スピログラフ(2次元)


スピログラフは遊んだ方も多いと思います。これです。
1024px-Spirograph
©Alexei Kouprianov/2007/CC-BY 2.5
スピログラフはトロコイドの特別な時です。スピログラフをもっと一般化したのがトロコイドです[2]。

図示すれば、スピログラフと言うのは
speq_compressed
という二つの円からなる軌道です。黄色の点線の長さが等しい、という束縛条件が課せられます。
数式は上のトロコイドと同じで
\(
\begin{equation}
\left\{
\begin{aligned}
x& = \left[(n-1)\cos t +h\cos((n-1)t)\right]/n \\
y& = \left[(n-1)\sin t +h\sin((n-1)t)\right]/n
\end{aligned}
\right.
\end{equation}
\)
と書けます。

もう少し考えを一般化して、周りを取り囲んでいる形状が円ではない時を考えましょう。その時の数式を考えます。
考え方はトロコイドと一緒ですが、もう少し拡張しましょう。

今、2つの媒介変数による軌道を持っていたとします。1つの媒介変数の軌道上を動かせばスピログラフの考えと同じになります。図で示すと以下のようになります。
spirograph_any_c
スピログラフは両方円であり、滑りが無い(cを決定する条件)場合に対応するわけです。ただ、円である必要性はないので、多角形であろうが、何だろうが数式上では書けるわけです。
興味深い事に、大きな軌道に沿って小さな軌道を動かした、と見ようが小さな軌道に沿って大きな軌道を動かしたとみても数式上では一緒なのです。面白いですね。

いくつか例を挙げます。
五角形上を動かす場合はこうです。
parameter1

数式として,
\(
\begin{equation}
\left\{
\begin{aligned}
x& = f_{1x}(t)+r\cdot f_{2x}(s\cdot t) \\
y& = f_{1y}(t)+r\cdot f_{2y}(s\cdot t)
\end{aligned}
\right.
\end{equation}
\)
と書き表すことにします。これを元にgnuplotのスクリプトを書けば以下のようになります。

色々に変化させた時の色々なときのグラフです。
spr2_any_compressed

rを綺麗な数字にしなければもっと複雑な図が得られます。
また、この考え方は3つの媒介変数の軌道、4つの媒介変数の軌道…として容易に拡張できます。
もっと複雑な模様が欲しければ、もう少し増やしてみましょう。

例えば3つの場合はこうなります。
parameter3_spi
このスクリプトを置いておきます。

この考えを拡張していくと”フーリエ級数の図示化”と言うのができるわけです。

実際にやっている方がいるので紹介しておきますね。

参考文献


[1]Is there an equation to describe regular polygons? -MATHEMATICS
[2]Hypotrochoid -Wolfram Mathworld

[3]Is there an equation to describe regular polygons? -Mathematics
2021/11/29追記)滑らかに星と円を遷移する場合、このページが丁寧です。