UP | HOME

座標軸の数値の増加を任意の関数にする

概要

[2021-03-08 Mon] 作成.
[2021-03-08 Mon]–[2021-03-12 Fri] 第一稿.

何らかの関数をグラフにする場合、一般的な xyx – y の軸であると都合が悪い場合がある。高校以降に登場する対数グラフはその解決策の一つであるが、他の関数におけるグラフはどうなるのだろうか。

通常のグラフ

軸の数字は x=[0,1,2,3,4, ],y=[0,1,2,3,4, ]x=[0, 1, 2, 3, 4, \dots], y=[0, 1, 2, 3, 4, \dots] という風に増加する。これを敢えて関数で表現すると x=x,y=yx=x, y=y となるが、これではどちらが軸か分からなくなる。ここで、軸の値の増加の仕方を表現するために添字 axis を付けて、

xaxis=x,yaxis=y \begin{aligned} x _{\mathrm{axis}} &= x, \\ y _{\mathrm{axis}} &= y \end{aligned}

とする。この時点ではグラフ上の関数が従うのは xaxis,yaxisx _{\mathrm{axis}}, y _{\mathrm{axis}} であって x,yx, y ではない。

とはいえ、今回はまだ軸の関数とグラフ上の関数が従う値が同じなので、分かりにくいかもしれない。

片対数グラフ

軸の数字は xaxis=[0,1,2,3,4, ],yaxis=[1,10,100,1000,10000, ]x _{\mathrm{axis}}=[0, 1, 2, 3, 4, \dots], y _{\mathrm{axis}}=[1, 10, 100, 1000, 10000, \dots] という風に増加する。これを先程のように添字で表現すると、

xaxis=x,yaxis=10y \begin{aligned} x _{\mathrm{axis}} &= x, \\ y _{\mathrm{axis}} &= 10 ^{y} \end{aligned}

とできる。

たとえばこのグラフ上に関数 y=x2+1y = x ^2+1 を描画したいとする。
もちろん (x,y)(x, y) の各点をとっていき、その点を繋ぐような曲線を書くという方法もある。しかしこれはグラフ用ソフトなどを用いる時に都合が悪い。
よって x,yx, y だけを通常の軸に戻す方法を考えた。

まず、 x=[0,1,2,3,4, ],y=[0,1,2,3,4, ]x=[0, 1, 2, 3, 4, \dots], y=[0, 1, 2, 3, 4, \dots] が基準であること、描画したいのは yaxis=xaxis2+1y _{\mathrm{axis}} = x _{\mathrm{axis}} ^2+1 であることを確認する。これを x,yx, y について解くと、 y=log10(x2+1)y = \log _{10}(x ^2+1) である。
そしてこの関数を x,yx, y 上に描く。最後に軸を yy から yaxisy _{\mathrm{axis}} にする。つまり

  • y=1y=1 の位置に値 yaxis=10y _{\mathrm{axis}}=10 と書く
  • y=2y=2 の位置に値 yaxis=100y _{\mathrm{axis}}=100 と書く
  • y=3y=3 の位置に値 yaxis=1000y _{\mathrm{axis}}=1000 と書く

両対数グラフ

要領は片対数と同じである。

xaxis=10x,yaxis=10y \begin{aligned} x _{\mathrm{axis}} &= 10 ^{x}, \\ y _{\mathrm{axis}} &= 10 ^{y} \end{aligned}

である。

x=[0,1,2,3,4, ],y=[0,1,2,3,4, ]x=[0, 1, 2, 3, 4, \dots], y=[0, 1, 2, 3, 4, \dots] が基準であること、描画したいのは yaxis=xaxis2+1y _{\mathrm{axis}} = x _{\mathrm{axis}} ^2+1 であることを確認する。

これを x,yx, y について解くと、 y=log10(102x+1)y = \log _{10}(10 ^{2x} +1) である。
そしてこの関数を x,yx, y 上に描く。最後に軸を xx から xaxisx _{\mathrm{axis}} に、 yy から yaxisy _{\mathrm{axis}} にする。

一般の関数の場合

xaxis=g(x),yaxis=h(y) \begin{aligned} x _{\mathrm{axis}} &= g(x), \\ y _{\mathrm{axis}} &= h(y) \end{aligned}

の時も同様である。

x=[0,1,2,3,4, ],y=[0,1,2,3,4, ]x=[0, 1, 2, 3, 4, \dots], y=[0, 1, 2, 3, 4, \dots] が基準であること、描画したいのは yaxis=f(x)y _{\mathrm{axis}} = f(x) であることを確認する。

これを x,yx, y について解くと、 y=h1(f(g(x))))y = h ^{-1}(f(g(x)))) である。
そしてこの関数を x,yx, y 上に描く。最後に軸を xx から xaxisx _{\mathrm{axis}} に、 yy から yaxisy _{\mathrm{axis}} にする。

ただし、軸の関数 g,hg, h は、変数と結果が一対一対応するものであることが重要である。上の例で用いた指数関数は一対一対応する。
一対一対応しない関数を軸に用いると、軸上で同じ位置に異なる値を持つことになってしまうからである。

これで様々な関数を軸にとれるようになるのだが、何を等間隔にするのかを意識するべきである。
たとえばアレニウスプロットをする場合、 1/x1/xxx軸にするのだが、 xaxis=1/xx _{\mathrm{axis}} = 1/x としてしまうと、[1,1/2,1/3,1/4, ][1, 1/2, 1/3, 1/4, \dots] が均等な幅になってしまう。なので関数やデータを変換(gnuplot なら plot data using (1.0/$1):2 など)して描画するのが良いだろう。

gnuplot での描画

一般の関数の場合で考えた関数を gnuplot で描画すると以下のようになる。ただし、関数 h1h ^{-1} は自分で計算して導出する必要がある。

set xrange [0:10]
set yrange [0:10]

set xtics ()
set for [i=0:10] xtics add (sprintf('%.2g', g(i)) i)

set ytics ()
set for [i=0:10] ytics add (sprintf('%.2g', h(i)) i)

plot h^{-1}(f(g(x)))

もちろん軸上の数字も任意の位置にできる。

set xrange [0:10]
set yrange [0:10]

set xtics (
    sprintf('%.2f', g(1)) 1, \
    sprintf('%.2f', g(5)) 5, \
    sprintf('%.2f', g(10)) 10 \
                    )

set ytics (
    sprintf('%.2f', h(1)) 1, \
    sprintf('%.2f', h(4)) 3, \
    sprintf('%.2f', h(8)) 8 \
                    )

plot h^{-1}(f(g(x)))

新しい軸上で [1,2,3,4, ][1, 2, 3, 4, \dots] を描画する

一般の関数の場合で考えると、

  • x=1x=1 の位置にラベル xaxis=g(1)x _{\mathrm{axis}} = g(1)
  • x=2x=2 の位置にラベル xaxis=g(2)x _{\mathrm{axis}} = g(2)
  • x=3x=3 の位置にラベル xaxis=g(3)x _{\mathrm{axis}} = g(3)

のように軸をとった。よって、

  • x=g1(1)x=g ^{-1}(1) の位置にラベル xaxis=1x _{\mathrm{axis}} = 1
  • x=g1(2)x=g ^{-1}(2) の位置にラベル xaxis=2x _{\mathrm{axis}} = 2
  • x=g1(3)x=g ^{-1}(3) の位置にラベル xaxis=3x _{\mathrm{axis}} = 3

のようにすればよい。

例: 無限大を見る

これが面白そうだと思ったので描いてみた。

reset
set encoding utf8
set terminal svg enhanced size 600,400 font "Arial:Bold,12" # svg
set size ratio 1 # 1:(x/y), -1 for 1:1 axes

set lmargin 0 # unset
set rmargin 8
set tmargin 2
set bmargin 2

set grid linetype 1 linewidth 0.75 linecolor "gray"

set title   font ",14" offset 0,-1      rotate by 0 center
set xlabel  font ",14" offset 0,1.0     rotate by 0 center # 3D: parallel
set ylabel  font ",14" offset 2.0,1.0   rotate by 90 center # 3D: parallel

set xtics   font ",12" offset -0.0,0.5  rotate by 0   mirror
set ytics   font ",12" offset 0.1,0     rotate by 0   mirror

f1(x) = 10**x
f2(x) = (x-1)*(x-2)*(x-3)
f3(x) = -x+7
f4(x) = x+sin(2*pi*x)
f5(x) = -2+sqrt(4-(x+1)**2)
f6(x) = -2-sqrt(4-(x+1)**2)

g(x) = x / (1.0 - abs(x))
g_inv(x) = x / (1.0 + abs(x))

h(x) = x / (1.0 - abs(x))
h_inv(x) = x / (1.0 + abs(x))

set samples 1000                             # default: 100

set title "F(x) = x / (1 - |x|) :  F( f( F^{-1}(x) ) )"
# key: http://dsl4.eee.u-ryukyu.ac.jp/DOCS/gnuplot/node96.html
set key right outside \
    box linestyle -1 linewidth 0.75 linecolor rgb "gray" \
    width -5 spacing 1.1 \
    title "f(x):" font ",12" # 凡例

# --- X AXIS ---
set xlabel "{/:Italic x}"
set xrange [-1:1] noreverse
set xtics ()
set xtics add ("-∞" -1, "∞" 1)
set xtics add ("-7" -7.0/8, "7" 7.0/8)
set xtics add ("-1/3" -1.0/4, "1/3" 1.0/4)
set for [i=-3:3] xtics add (sprintf("%d", i) g_inv(1.0*i))

# --- Y AXIS ---
set ylabel "{/:Italic y}"
set yrange [-1:1] noreverse
set ytics ()
set ytics add ("-∞" -1, "∞" 1)
set ytics add ("-7" -7.0/8, "7" 7.0/8)
set ytics add ("-1/3" -1.0/4, "1/3" 1.0/4)
set for [i=-3:3] ytics add (sprintf("%d", i) g_inv(1.0*i))
# set for [i=-10:4:2] ytics add (sprintf("10^{%.2g}", i/100.0) i/100.0)

plot \
     h_inv(f1(g(x))) with lines lw 2 lt 1 title "10^{x}", \
     h_inv(f2(g(x))) with lines lw 2 lt 2 title "(x-1)(x-2)(x-3)" , \
     h_inv(f3(g(x))) with lines lw 2 lt 3 title "-x+7" , \
     h_inv(f4(g(x))) with lines lw 2 lt 4 title "x+sin(2πx)" , \
     h_inv(f5(g(x))) with lines lw 2 lt 6 title "-2+sqrt((x+1)^2-2^2)" , \
     h_inv(f6(g(x))) with lines lw 2 lt 6 title "-2-sqrt((x+1)^2-2^2)" #, \
Sorry, your browser does not support SVG.

さらに両対数を間に挟んだが、あまり使い道が思い浮かばない。

reset
set encoding utf8
set terminal svg enhanced size 400,600 font "Arial:Bold,12" # svg
set size ratio 1 # 1:(x/y), -1 for 1:1 axes

set lmargin 7 # unset
set rmargin 1
set tmargin 1
set bmargin 2

set grid linetype 1 linewidth 0.75 linecolor "gray"

set title   font ",14" offset 0,-1      rotate by 0 center
set xlabel  font ",14" offset 0,1.0     rotate by 0 center # 3D: parallel
set ylabel  font ",14" offset 2.0,1.0   rotate by 90 center # 3D: parallel

set xtics   font ",12" offset -0.0,0.5  rotate by 0   mirror
set ytics   font ",12" offset 0.1,0     rotate by 0   mirror

f1(x) = 10**x-1
f2(x) = exp((x-1)*(x-0.1)/(x-10)/(x-0.001)))

g(x) = x / (1.0 - abs(x))
g_inv(x) = x / (1.0 + abs(x))

h(x) = 10**x
h_inv(x) = log10(x)

set samples 4000                             # default: 100

set title "F( log10( f( 10**( F^{-1}(x) ) ) ) )"
set key below \
    box linestyle -1 linewidth 0.75 linecolor rgb "gray" \
    width -5 spacing 1.1 \
    title "f(x):" font ",12" # 凡例

# --- X AXIS ---
set xlabel "{/:Italic x}"
set xrange [-1:1] noreverse
set xtics ()
set xtics add ("0" -1, "∞" 1)
set xtics add ("10^{-7}" -7.0/8, "10^{7}" 7.0/8)
set xtics add ("10^{-1/3}" -1.0/4, "10^{1/3}" 1.0/4)
set for [i=-3:3] xtics add (sprintf("10^{%d}", i) g_inv(1.0*i))

# --- Y AXIS ---
set ylabel "{/:Italic y}"
set yrange [-1:1] noreverse
set ytics ()
set ytics add ("0" -1, "∞" 1)
set ytics add ("10^{-7}" -7.0/8, "10^{7}" 7.0/8)
set ytics add ("10^{-1/3}" -1.0/4, "10^{1/3}" 1.0/4)
set for [i=-3:3] ytics add (sprintf("10^{%d}", i) g_inv(1.0*i))

plot \
     g_inv(h_inv(f1(h(g(x))))) with lines lw 2 lt 1 title "10^{x} - 1" , \
     g_inv(h_inv(f2(h(g(x))))) with lines lw 2 lt 2 title "{/=8 exp((x-0.1)(x-1)/(x-0.001)(x-10))}" # , \
Sorry, your browser does not support SVG.

Created: 2021-03-17 Wed 17:05

Validate