例題演習matplotlib(5)：対数グラフ

# 例題5.：対数グラフ
対数グラフの設定方法を学ぶ．

**例題演習matplotlibのまとめ**
https://qiita.com/s4s/items/026aa83b881b640b8b23

## 例(1)：サンプルコード
Y軸が対数となる，片対数グラフを例としたサンプルコードを示す．

```python:plot05_example1.py
import numpy as np                  # numpy
import matplotlib.pyplot as plt     # matplotlib plt
import matplotlib.ticker as ticker  # matplotlib ticker


def main():
    '''main program'''

    # setting
    f_out = 'graph05_example1.png'   # output file (figure)

    # data
    x = np.arange(0, 10.1, 0.1)
    y1 = np.exp(x)
    #y2 = 1e5 * np.exp(-x)
    y2 = x
    data = {'p1': [x, y1, r'$y=\exp(x)$'],  # packing
            'p2': [x, y2, r'$y=x$']}

    # plot graph
    run_plot(f_out, data)


def run_plot(f_out, data):
    '''plot graph
    [input]
    f_out: output file name
    data: data for plotting (x, y, label)
    '''

    # (0) setting of matplotlib
    # graph
    gx = 14                     # graph size of x [cm]
    gy = 6                      # graph size of y [cm]
    dpi = 200                   # graph DPI (100～600程度)

    # font
    f_family = 'IPApGothic'     # font (sans-serif, serif, IPApGothic)
    font_ax = {'size': 10, 'color': 'k'}  # 軸ラベルのフォント
    fs_le = 9                             # 凡例のフォントサイズ
    fs_ma = 9                             # 主目盛りのフォントサイズ

    # 軸ラベル
    x_label = 'X'               # x軸ラベル
    y_label = 'Y'               # y軸ラベル

    # 軸範囲
    x_s = 0                     # x軸の最小値
    x_e = 10                    # x軸の最大値
    y_s = 0.1                  # y軸の最小値
    y_e = 1e5                   # y軸の最大値

    # 目盛り
    x_ma = 1                    # x軸の主目盛り間隔
    x_mi = 0.2                  # x軸の副目盛り間隔
    y_ma = 0.5                  # y軸の主目盛り間隔
    y_mi = 0.1                  # y軸の副目盛り間隔

    # (A) Figure
    # (A.1) Font or default parameter
    # https://matplotlib.org/stable/api/matplotlib_configuration_api.html
    plt.rcParams['font.family'] = f_family

    # (A.2) Figureの作成
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.figure.html
    # [Returns]
    #   Figureオブジェクトが返される。
    # [Parameter]
    # figsize=(6.4,4.8): グラフサイズ(x,y), 1[cm]=1/2.54[in]
    # dpi=100: 出力DPI
    tl = False                  # Figureのスペース自動調整
    fc = 'w'                    # Figureの背景色
    ec = None                   # 枠線の色
    lw = None                   # 枠線の幅
    fig = plt.figure(figsize=(gx/2.54, gy/2.54), dpi=dpi,
                     tight_layout=tl, facecolor=fc, edgecolor=ec,
                     linewidth=lw)

    # (A.3) グラフ間隔の調整(pltまたはfig)
    # bottom等はfigure()でtigit_layout=Trueにすれば不要
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplots_adjust.html
    bottom = 0.18                # グラフ下側の位置(0～1)
    top = 0.95                  # グラフ上側の位置(0～1)
    left = 0.12                 # グラフ左側の位置(0～1)
    right = 0.97                # グラフ右側の位置(0～1)
    hspace = 0.2                # グラフ(Axes)間の上下余白
    wspace = 0.2                # グラフ(Axes)間の左右余白
    fig.subplots_adjust(bottom=bottom, top=top, left=left, right=right,
                        hspace=hspace, wspace=wspace)

    # (B) Axes
    # (B.1) Axesの追加
    # 複数のグラフをタイル状に作成することができる。
    # 複数グラフの配置を細かく設定する場合はadd_axes()やadd_gridspec()。
    # https://matplotlib.org/stable/api/figure_api.html
    # [Returns]
    #   Axesオブジェクトが返される。
    # [Parameter]
    # *args=(1,1,1): 行番号,列番号,インデックス
    #   1つのFigureに複数のAxesを作る場合に指定する。
    #   add_subplot(2,1,1): 2行のAxesを作り、その1番目(上側)
    #   add_subplot(211): 2,1,1と同じだが、簡略記法
    # projection='rectilinear': グラフの投影法(polarなど)
    # sharex: x軸を共有する際に、共有元のAxisを指定する。
    # sharey: sharexのy軸版
    # label: Axesに対する凡例名（通常は使わない）
    n_row = 1                   # 全グラフの行数
    n_col = 1                   # 全グラフの列数
    n_ind = 1                   # グラフ番号
    fc = 'w'                    # Axesの背景色（通常は白）
    ax = fig.add_subplot(n_row, n_col, n_ind, fc=fc)

    # (B.2) 軸ラベル(axis label)の設定
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xlabel.html
    # [Parameter]
    # xlabel: 軸ラベル
    # loc='center': 軸ラベル位置(x: left,center,right; y:bottom,center,top)
    # labelpad: 軸ラベルと軸間の余白
    # fonddict: 軸ラベルのText設定
    ax.set_xlabel(x_label, fontdict=font_ax)  # x軸ラベルの設定
    ax.set_ylabel(y_label, fontdict=font_ax)  # y軸ラベルの設定

    # (B.3) 軸の種類の設定
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xscale.html
    xscale = 'linear'          # x軸の種類(linear, log, symlog, logit)
    yscale = 'log'             # y軸の種類(linear, log, symlog, logit)
    ax.set_xscale(xscale)      # x軸の種類
    ax.set_yscale(yscale)      # y軸の種類

    # (B.4) 軸の範囲の設定
    # 自動で設定する場合は、auto=Trueのみにする
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xlim.html
    ax.set_xlim(x_s, x_e, auto=False)  # x軸の範囲
    ax.set_ylim(y_s, y_e, auto=False)  # y軸の範囲

    # (B.5) 軸のアスペクト比
    # x軸とy軸の比率を強制的に設定する場合に行う。
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_aspect.html
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_box_aspect.html
    asp_a = 'auto'          # auto:自動, [数値]:x,yの比率
    asp_b = None            # None:自動, [数値]:x,yのグラフ長さの比率
    ax.set_aspect(asp_a)    # X軸とY軸の比率を設定する
    ax.set_box_aspect(asp_b)   # X軸とY軸のグラフ長さの比率を設定する

    # (B.6) 目盛り関係の設定
    # (B.6.1)主目盛りの位置(Locator)
    # https://matplotlib.org/stable/api/ticker_api.html
    mal_x = ticker.MultipleLocator(x_ma)  # 等間隔目盛り
    # mal_x = ticker.IndexLocator(x_ma, x_off) # 等間隔目盛り(+offset)
    # mal_x = ticker.LogLocator(base=10) # 対数目盛り
    # mal_x = ticker.AutoLocator()         # 自動目盛り
    # mal_x = ticker.NullLocator()         # 目盛りなし
    # mal_x = ticker.LinearLocator(nx_ma)  # 個数指定目盛り
    # mal_x = ticker.FixedLocator([0, 1, 3]) # 位置指定目盛り
    # mal_y = ticker.MultipleLocator(y_ma)  # 等間隔目盛り
    # mal_y = ticker.IndexLocator(y_ma, y_off)  # 等間隔目盛り(+offset)
    mal_y = ticker.LogLocator(base=10)     # 対数目盛り
    # mal_y = ticker.AutoLocator()         # 自動目盛り
    # mal_y = ticker.NullLocator()         # 目盛りなし
    # mal_y = ticker.LinearLocator(ny_ma)  # 個数指定目盛り
    # mal_y = ticker.FixedLocator([-1, 0, 1]) # 位置指定目盛り
    ax.xaxis.set_major_locator(mal_x)    # x軸の主目盛り間隔の設定
    ax.yaxis.set_major_locator(mal_y)    # y軸の主目盛り間隔の設定

    # (B.6.2)主目盛りの表記(Formatter)
    # https://matplotlib.org/stable/api/ticker_api.html
    maf_x = ticker.ScalarFormatter()  # 数値
    # maf_x = ticker.NullFormatter() # 目盛り表記なし
    # maf_x = ticker.FixedFormatter(['A','B','C','D','E','F']) # 指定表記
    # maf_x = ticker.StrMethodFormatter('{x:.1f}m') # format記法
    # maf_x = ticker.LogFormatterMathtext(base=10)  # log記法(10^x)
    # maf_y = ticker.ScalarFormatter()  # 数値
    # maf_y = ticker.NullFormatter() # 目盛り表記なし
    # maf_y = ticker.FixedFormatter(['A','B','C','D','E','F']) # 指定表記
    # maf_y = ticker.StrMethodFormatter('{x:.1f}m') # format記法
    maf_y = ticker.LogFormatterMathtext(base=10)  # log記法(10^x)
    ax.xaxis.set_major_formatter(maf_x)  # x軸の主目盛り表記の設定
    ax.yaxis.set_major_formatter(maf_y)  # y軸の主目盛り表記の設定

    # (B.6.3) 副目盛りの位置(Locator)
    # https://matplotlib.org/stable/api/ticker_api.html
    mil_x = ticker.MultipleLocator(x_mi)  # 等間隔目盛り
    # mil_x = ticker.IndexLocator(x_mi, x_off)  # 等間隔目盛り(+offset)
    # mil_x = ticker.LogLocator(base=10, subs=np.arange(2, 10)*0.1) # 対数目盛り
    # mil_x = ticker.AutoLocator()         # 自動目盛り
    # mil_x = ticker.NullLocator()         # 目盛りなし
    # mil_x = ticker.LinearLocator(nx_mi)  # 個数指定目盛り
    # mil_y = ticker.MultipleLocator(y_mi)  # 等間隔目盛り
    # mil_y = ticker.IndexLocator(y_mi, y_off)  # 等間隔目盛り(+offset)
    mil_y = ticker.LogLocator(base=10, subs=np.arange(2, 10)*0.1) # 対数目盛り
    # mil_y = ticker.AutoLocator()         # 自動目盛り
    # mil_y = ticker.NullLocator()         # 目盛りなし
    # mil_y = ticker.LinearLocator(ny_mi)  # 個数指定目盛り
    ax.xaxis.set_minor_locator(mil_x)  # x軸の副目盛り間隔の設定
    ax.yaxis.set_minor_locator(mil_y)  # y軸の副目盛り間隔の設定

    # (B.6.4) 副目盛りの表記(Formatter)
    # https://matplotlib.org/stable/api/ticker_api.html
    mif_x = ticker.NullFormatter()       # 目盛り表記なし
    mif_y = ticker.NullFormatter()       # 目盛り表記なし
    ax.xaxis.set_minor_formatter(mif_x)  # x軸の副目盛り表記の設定
    ax.yaxis.set_minor_formatter(mif_y)  # y軸の副目盛り表記の設定

    # (B.6.5) 目盛り関連の細部の設定
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.tick_params.html
    # [Parameter]
    # axis: 対象軸(x, y, both)
    # which: major, minor, both
    # labelsize: フォントサイズ
    # top, right, bottom, left: Tickを表記する場所(Trueで表記)
    # labeltop: Trueで上側にも目盛りを付ける(labelrightも同様)
    # labelrotation: 目盛りの表記角度
    # labelcolor: 目盛り表記の色
    # pad: 軸と目盛りの間隔
    # color: 目盛り線の色
    ax.tick_params(axis='both', which='major', labelsize=fs_ma,
                   top=True, right=True)
    ax.tick_params(axis='both', which='minor', top=True, right=True)

    # (B.7) グリッドの設定
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.grid.html
    gb = True   # 出力の有無(Falseかつ、lsなどの指定なしで、出力なし)
    which = 'major'  # 目盛りの指定(major, minor, both)
    axis = 'y'       # X,Y軸の指定(x, y, both)
    color = 'gray'   # 線色
    ls = '-'         # 線種('-', '--', '-.', ':')
    lw = 0.5         # 線幅
    # ax.grid(b=gb, which=which, axis=axis)  # Falseの場合
    ax.grid(b=gb, which=which, axis=axis, c=color, ls=ls, lw=lw)

    # (B.8) 直線
    # axhline(), axvline(): 横線, 縦線（端から端まで）
    # axhspan(), asvspan(): 横線, 縦線（始点と終点指定）
    # axline(): 直線
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axhline.html
    # [Parameter]
    # py = 0                      # 横線の位置(y座標)
    # color = 'k'                 # 線色
    # ls = '-'                    # 線種('-', '--', '-.', ':')
    # lw = 0.5                    # 線幅
    # ax.axhline(y=py, c=color, ls=ls, lw=lw)

    # (C) Plot
    # (C.1) plot(): 折れ線グラフ
    # 散布図はscatter()
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html
    # [Returns]
    #   Line2Dオブジェクト（配列）が返される。
    # [Parameter]
    # *args: xデータ, yデータ, [fmt]
    #   x,yデータはx軸とy軸のデータ（リストなど）
    #   fmtは線や点の簡易的記法による指定
    # *kwargs: Line2Dの設定値（多数あり）
    d_x = data['p1'][0]         # x data（適宜変更）
    d_y = data['p1'][1]         # y data（適宜変更）
    label = data['p1'][2]       # 凡例（なしはNone）
    ls = '-'                       # 線種('-', '--', '-.', ':')
    lw = 0.7                       # 線幅
    color = 'b'                    # 線色(k, r, g, b, etc.)
    marker = 'None'     # marker(o, s, v, ^, D, +, x, etc.; None=なし)
    mec = 'k'           # markerの線色(k, r, g, b, etc.)
    mew = 0.5           # markerの線幅
    mfc = 'w'           # markerの色(none, k, r, g, b, w, etc.)
    ms = 2              # markerサイズ
    markevery = None    # markerの出力間隔(None=全部, 2は2個毎)
    p2 = ax.plot(d_x, d_y, label=label, ls=ls, lw=lw, c=color,
                 marker=marker, mec=mec, mew=mew, mfc=mfc, ms=ms,
                 markevery=markevery)

    # (C.1) plot(): 折れ線グラフ
    d_x = data['p2'][0]         # x data（適宜変更）
    d_y = data['p2'][1]         # y data（適宜変更）
    label = data['p2'][2]       # 凡例（なしはNone）
    ls = '-'                       # 線種('-', '--', '-.', ':')
    lw = 0.7                       # 線幅
    color = 'r'                    # 線色(k, r, g, b, etc.)
    marker = 'None'        # marker(o, s, v, ^, D, +, x, etc.; None=なし)
    mec = 'k'           # markerの線色(k, r, g, b, etc.)
    mew = 0.5           # markerの線幅
    mfc = 'w'           # markerの色(none, k, r, g, b, w, etc.)
    ms = 2              # markerサイズ
    markevery = None    # markerの出力間隔(None=全部, 2は2個毎)
    p3 = ax.plot(d_x, d_y, label=label, ls=ls, lw=lw, c=color,
                 marker=marker, mec=mec, mew=mew, mfc=mfc, ms=ms,
                 markevery=markevery)
    

    # (D) Others: 凡例、テキストなど
    # (D.1) 凡例
    # (D.1.1) 凡例データの一覧を作成
    handles, labels = ax.get_legend_handles_labels()

    # (D.1.2) 凡例の作成
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.legend.html
    anc = (0,  1)                # 凡例の配置場所(0～1の相対位置)
    loc = 'upper left'  # 配置箇所:upper,center,lower; left,center,right; best
    ti = ''              # 凡例のタイトル(なし=None or '')
    ti_fs = 9            # 凡例のタイトルのフォントサイズ
    ncol = 1             # 凡例の列数
    fc = 'w'             # 凡例の背景色（なし=none）
    ec = 'k'             # 枠線の色（なし=none）
    fa = 1.0             # 透明度(0で透明, 1で透明なし)
    bp = 0.5             # 凡例の枠の余白(default=0.4)
    ms = 1.0             # マーカーの倍率(default=1.0)
    sha = False           # True:影付き、False:影なし
    fb = True            # 凡例の角：True:丸、False:四角
    bap = 0.8            # 凡例の外側の余白(default=0.5)
    ls = 0.5             # 凡例間の上下余白
    cs = 2.0             # 凡例間の左右余白
    legend = ax.legend(handles, labels, title=ti,
                       title_fontsize=ti_fs, loc=loc,
                       bbox_to_anchor=anc, ncol=ncol, facecolor=fc,
                       edgecolor=ec, framealpha=fa, fontsize=fs_le,
                       borderpad=bp, shadow=sha, markerscale=ms,
                       fancybox=fb, labelspacing=ls, columnspacing=cs,
                       borderaxespad=bap)

    # (D.1.3) 凡例の細かい設定
    legend.get_frame().set_linestyle('-')  # 枠線の種類
    legend.get_frame().set_linewidth(0.5)  # 枠線の太さ

    # (D.2) テキスト
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.text.html
    # txt = '(a) Test Plot'    # テキスト文字列
    # px = 0.97                # x位置(transformで基準座標の変更)
    # py = 0.05                # y位置(transformで基準座標の変更)
    # tf = ax.transAxes        # 基準座標(ax.transAxes, fig.transFigure)
    # ha = 'right'             # 左右位置(left, center, right)
    # va = 'bottom'            # 上下位置(bottom, center, top, baseline)
    # rot = 0                  # 回転角度(左回転)
    # color = 'k'              # テキストの色
    # font_tx = {'size': 10}   # テキストのフォント
    # ax.text(x=px, y=py, s=txt, font=font_tx, ha=ha, va=va, color=color,
    #         rotation=rot, transform=tf)

    # (E) save figure
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html
    # [Parameters]
    # fname: 出力ファイル名
    # dpi: 出力DPI（Figure設定時のdpiが優先）
    print(f'write: {f_out}')
    plt.savefig(fname=f_out)    # save figure

    # (F) close
    plt.close()


if __name__ == '__main__':
    main()
```

グラフは次のようになる．
![graph05_example1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/25a7918f-bbe0-7601-c291-41a73039d858.png)

# 解説
サンプルコードを基に，グラフ表記の変更方法などを説明する．

## 対数グラフへの変更方法
**(1) 対数にする軸の範囲にマイナスが含まれないようにする．**

```python
    # 軸範囲
    x_s = 0                     # x軸の最小値
    x_e = 10                    # x軸の最大値
    y_s = 0.1                   # y軸の最小値
    y_e = 1e5                   # y軸の最大値
```

**(2) 軸の種類を`linear`（線形）から`log`（対数）に変更する(B.3)．**
(B.3)で，軸の種類を変更する．対数は`log`となる．
なお，特殊な対数グラフとして`symlog`と`logit`があるけれども，ほとんど使われないので，説明は割愛する．

```python
    # (B.3) 軸の種類の設定
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xscale.html
    xscale = 'linear'          # x軸の種類(linear, log, symlog, logit)
    yscale = 'log'             # y軸の種類(linear, log, symlog, logit)
    ax.set_xscale(xscale)      # x軸の種類
    ax.set_yscale(yscale)      # y軸の種類
```

ひとまず，これで対数グラフにはなる．通常は，上記に加えて目盛りの変更が必要となる．

**(3) 目盛りの設定変更(B.6)**
サンプルコードのY軸の目盛り設定だけ抜き出して詳しくみてみる．
まず，主目盛りの設定は以下の通り．

```python
    # (B.6) 目盛り関係の設定
    # (B.6.1)主目盛りの位置(Locator)
    mal_y = ticker.LogLocator(base=10)     # 対数目盛り
    ax.yaxis.set_major_locator(mal_y)    # y軸の主目盛り間隔の設定

    # (B.6.2)主目盛りの表記(Formatter)
    maf_y = ticker.LogFormatterMathtext(base=10)  # log記法(10^x)
    ax.yaxis.set_major_formatter(maf_y)  # y軸の主目盛り表記の設定
```

目盛り場所を設定するLocatorには，対数用のLocatorである`LogLocator()`を用いている．主目盛りの設定パラメータ`base`は，対数の底を指定する．

目盛り表記を設定するFormatterには，`LogFormatterMathext()`を用いている．これは，上の図のように，$10^5$という表記になる．他の表記については，後ほど例を示す．

次に，副目盛りの設定は以下の通り．

```python
    # (B.6.3) 副目盛りの位置(Locator)
    mil_y = ticker.LogLocator(base=10, subs=np.arange(2, 10)*0.1) # 対数目盛り
    ax.yaxis.set_minor_locator(mil_y)  # y軸の副目盛り間隔の設定

    # (B.6.4) 副目盛りの表記(Formatter)
    mif_y = ticker.NullFormatter()       # 目盛り表記なし
    ax.yaxis.set_minor_formatter(mif_y)  # y軸の副目盛り表記の設定
```

副目盛りの位置は主目盛りと同じく，`LogLocator()`だが，パラメータに`subs`がある．例の場合は，(0.2, 0.3, ..., 0.9)の位置を指定しており，0.1～1.0の間に9本の副目盛りが作成されることとなる．
なお，`subs='auto'`としておけば，自動で設定されるので，良く分からなければautoにしておけばよい．

副目盛りの表記は，例では表記なし（`NullFormatter()`）としている．



## 例(2)：サブグリッド線
対数グラフでは，サブグリッド（副グリッド）の線も示すことがある．
その場合は，(B.7)で，サブグリッドの設定を加えれば良い．

```python
    # (B.7) グリッドの設定
    # https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.grid.html
    gb = True   # 出力の有無(Falseかつ、lsなどの指定なしで、出力なし)
    which = 'major'  # 目盛りの指定(major, minor, both)
    axis = 'y'       # X,Y軸の指定(x, y, both)
    color = 'gray'   # 線色
    ls = '-'         # 線種('-', '--', '-.', ':')
    lw = 0.5         # 線幅
    # ax.grid(b=gb, which=which, axis=axis)  # Falseの場合
    ax.grid(b=gb, which=which, axis=axis, c=color, ls=ls, lw=lw)

    gb = True   # 出力の有無(Falseかつ、lsなどの指定なしで、出力なし)
    which = 'minor'  # 目盛りの指定(major, minor, both)
    axis = 'y'       # X,Y軸の指定(x, y, both)
    color = 'gray'   # 線色
    ls = '-'         # 線種('-', '--', '-.', ':')
    lw = 0.3         # 線幅
    ax.grid(b=gb, which=which, axis=axis, c=color, ls=ls, lw=lw)
```

グラフは次のようになり，Y軸にサブグリッドの線が加わっている．
![graph05_example2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/ac5d2d76-e427-1af4-c004-d22b570efade.png)


## 例(3)：非常に広い範囲の対数目盛りの表記方法（目盛りの強制表示）
Y軸の範囲の上限値を，$10^5$から$10^7$に変化させると，次のように，Y軸の主目盛りの数が間引きされ，副目盛りは表示されなくなる．
![graph05_example3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/1964e26f-8483-a886-b312-08de46a94b2e.png)

これはmatplotlibが目盛りを自動調整するためだが，強制的に出力させたい場合もある．
その場合は，`LogFormatter()`のパラメータ`numticks`（ticksの上限数）を設定する．サンプルコードでは，以下のように変更する．

```python
    mal_y = ticker.LogLocator(base=10, numticks=9)  # 対数目盛り
```

作成されるグラフでは，主目盛りが9個に増えている．
![graph05_example3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/8248af5d-510c-53f9-2b79-a507a3a6af7a.png)

さらに，副目盛りも強制出力するには，以下のように変更すれば良い．
なお，`numticks`は出力する目盛り数の上限値なので，999などと設定しても結果は同じ．

```python
    mil_y = ticker.LogLocator(base=10, subs=np.arange(2, 10)*0.1,
                              numticks=8*9)  # 対数目盛り
```

グラフは以下のようになる．
![graph05_example3_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/29a48e0f-61c6-cf2c-d7a1-c889a374fd30.png)



## 例(4)：E表記法（コンピューター的指数表記）
E表記法とは，「10^5」を「1e+05」と表記する方法で，プログラミング言語やExcelではおなじみの表記方法である．E表記法は，Formatterに，`LogFormatter()`を使えば良い（あまり一般的でないので，サンプルコードからは除外している）．
サンプルコードでは，以下の部分を変更する．

```python
    # (A.3) グラフ間隔の調整(pltまたはfig)
    left = 0.14                 # グラフ左側の位置(0～1)

    # (B.6.2)主目盛りの表記(Formatter)
    maf_y = ticker.LogFormatter(base=10)  # log記法(e表記)
```

グラフは以下のようになる．1～$10^4$までは整数で表記され，1以下と$10^4$以上はE表記となる．
![graph05_example4_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/209d200e-b62f-f4a0-e841-9b6324b83850.png)


## 例(5)：副目盛りの位置変更
あまり一般的ではないが，常用対数の副目盛りを0.2と0.5の2つとする場合がある（倍半分が分かりやすい）．
下記のように，副目盛りの`LogLocator`のパラメータ`subs`を変更する．

```python
    # (B.6.3) 副目盛りの位置(Locator)
    mil_y = ticker.LogLocator(base=10, subs=[0.2, 0.5]) # 対数目盛り
```

グラフは次のようになる．
![graph05_example5_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/4408f41a-8200-fd7e-9c33-bad5d1ca50a8.png)

# 演習
サンプルコードを基に，下記の演習問題に解答せよ．
解答はコメント欄を参照．

## 演習(1)：両対数グラフ
次の図のように，X軸も対数グラフにせよ．
※X軸の範囲を0.1～10，目盛りを対数用に変更．
![graph05_hw01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/bedffaca-313b-c249-34ec-576eb0a7885b.png)

## 演習(2)：グリッド線の変更
演習(1)の図から，グリッド線を追加し，以下の図のように変更せよ．
※グリッド線はX軸とY軸両方で作成，メイングリッド線は線幅0.5の実線，サブグリッド線は線幅0.3の破線．
![graph05_hw02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195213/8e77f5e1-ae9f-afde-2ff3-b4489a9e43a5.png)