第9章 軸・枠回り
pygmt.Figure.basemap(frame=\<>)などで枠や軸を作ることができる.
frameはfig.plot()で指定しても良い.
軸目盛り,グリッドの追加
基本
frame引数において’agf’の文字列でそれぞれアノテーション(目盛り数値),グリッド,目盛り線の有無を指定する.例えば’g’のみにするとグリッドのみが追加される.
また,それぞれの文字のあとに数字を入れることで間隔を指定できる:
    ...,
    frame = 'a<アノテーション間隔>g<グリッド間隔>f<目盛り線間隔>',
    ...,
さらに配列にして複数にわけ,先頭にx, yをつけることで軸ごとに設定を指定できる:
    ...,
    frame = ['x<agf>','y<agf>']
    ...,
上下左右別のframeの追加
frame = []の中を「, 」で区切り,次の例のようにする:
fig.basemap(
frame=['<NEWS news tlrb>','<agf>'],
)
前半の部分で軸とアノテーションの有無を上下左右ごとに指定している.上下左右は東西南北のnewsまたはNEWS,さらにあるいはtlrb (top, left, right, bottomの頭文字) で表す. 小文字のnewsで書くと軸と目盛り線のみが描画され,大文字NEWSで書くとアノテーションがつく.何も書かなかった方向は軸が描画されない.
またtlrbはframeのタイプ(cf. 第*※相互参照無効*節)が「plain」のときに有効で(fancy–縞々の枠–のときはnewsと同じか).newsでは描画される目盛り線も消えて枠線のみを残すことができる.
<注意>basemap()より先にplot()などを使うと,先に勝手に左と下にアノテーションがついた軸が描画されてしまう場合がある.この状態だと後に記したbasemap()で’NEsw’としても,重ね描きの結果,先にplotで作成された’NEWS’の見た目が残ってしまう.
例)plain枠におけるNEWS,news,tlrb,指定なしの違い.出力:図*※相互参照無効*
import pygmt
fig = pygmt.Figure()
fig.basemap(
    region = [0,100,0,50],
    projection = "X6c/3c",
    frame = ['tWs','af'],
)
fig.show()

plain枠におけるframeの上下左右別指定.上がt, 左がE, 下がb, 右が指定なし.fancy枠ではnewsとtlrbの違いはなしか.
目盛りと補助目盛りの追加
    # 主目盛り
    frame = "p<agf>"
    # 補助目盛り
    frame = "s<agf>"
frameでアノテーションなどを指定するとき,初めにs,pをつければそれぞれ主,補助目盛りになるようだ.しかしうまくいかないときもある気がする.
ここでsが主目盛りなのだが,これを守って主・補助の両方を指定すると図*※相互参照無効*のように主目盛り線がやたらと長くなり不格好. こうなるのは補助目盛りのアノテーションのスペースを確保するためであろうか.
なので主目盛りのみにアノテーションを付す場合は, 警告メッセージが大量に出るがあえて逆に指定する方が図*※相互参照無効*のように目盛り線の長さは自然になる.
あるいは目盛り線の長さを明示的に指定して調整することもできる (cf. 第*※相互参照無効*節).
-->アノテーションの調整
緯度経度の書式
with pygmt.config(
    FORMAT_GEO_MAP = "ddd.xx"
    ):
    ...
地図のプロットの場合,枠のラベルの書式を度分ではなく小数度にできる. 例)緯度経度の書式.出力:図*※相互参照無効*
import pygmt
fig = pygmt.Figure()
with pygmt.config(
    FONT = '8p'
    ):
    with pygmt.config(
        FORMAT_GEO_MAP = 'ddd',
    ):
        fig.basemap(
            frame = ['agf'],
            region = [0,10,0,10],
            projection = 'M3c',
        )
        fig.text(
            position = 'CT',
            text = 'ddd',
            justify = 'CB',
            offset = '0/10p',
            no_clip = True,
            font = '9p',
        )
    fig.shift_origin('4.5c')
    with pygmt.config(
        FORMAT_GEO_MAP = 'ddd.x',
    ):
        fig.basemap(
            frame = ['agf'],
            region = [0,10,0,10],
            projection = 'M3c',
        )
        fig.text(
            position = 'CT',
            text = 'ddd.x',
            justify = 'CB',
            offset = '0/10p',
            no_clip = True,
            font = '9p',
        )
    fig.shift_origin('4.5c')
    with pygmt.config(
        FORMAT_GEO_MAP = 'ddd.xx',
    ):
        fig.basemap(
            frame = ['agf'],
            region = [0,10,0,10],
            projection = 'M3c',
        )
        fig.text(
            position = 'CT',
            text = 'ddd.xx',
            justify = 'CB',
            offset = '0/10p',
            no_clip = True,
            font = '9p',
        )
fig.show()

アノテーションの緯度経度の書式を小数点形式に変更.
回転
    ...,
    frame = '...+a<angle(°)>'
    ...,
projectionが「X」の場合のみ. アノテーションを回転できる. 地図で用いようとすると「basemap [ERROR]: Option -B: Cannot use +a for geographic basemaps」というエラーが出て使用できない. 例)出力:図*※相互参照無効*
import pygmt
fig = pygmt.Figure()
fig.basemap(
    region = [0,10,0,10],
    projection = 'X4c',
    frame = ['neS','agf'],
)
with pygmt.config(
    FONT_ANNOT = '8p,red',
):
    fig.basemap(
        region = [0,10,0,10],
        projection = 'X4c',
        frame = ['W','yagf+a90'],
    )
fig.show()

アノテーションの回転(直交座標の場合のみ可能).
グリッド線の調整
スタイルの変更
with pygmt.config(
    # 主グリッド
    MAP_GRID_PEN_PRIMARY = '<width,color,style>'
    # 補助グリッド
    MAP_GRID_PEN_SECONDARY = '<width,color,style>'
    ):
    ...
このwith構文内のメソッドでプロットしたグリッドにスタイルを適用できる. スタイルはplotメソッドにおける線のスタイルと共通.
なお,styleについて「dash」(あるいは「- -」)の場合は太さの指定が適用されないようだ.代わりにwidthで破線の間隔が指定されるようだ.
例)出力:図*※相互参照無効*
import pygmt
fig = pygmt.Figure()
with pygmt.config(
    MAP_GRID_PEN_PRIMARY = '0.5p,blue,.',
    MAP_GRID_PEN_SECONDARY = '0.8p,red,:',
    ):
    fig.basemap(
        region = [0,10,0,10],
        projection = 'X4c',
        frame = ['pg0.5f0.5','sa2g2f2'],
    )
fig.show()

主グリッド(赤),補助グリッド(青)のスタイルの指定.
座標軸・目盛りの調整
軸ラベルの追加
    ...,
    frame=['x<agf>+l<xlabel>', 'y<agf>+<ylabel>'],
    ...,
x, yなどの軸ごとに「+l」を付加することでその軸のラベルを加えることができる.
対数軸
projection = 'X<x-size>l/<y-size>l'
projectionで直交座標を指定したうえで,自然対数にしたい軸のサイズの後に「l」をつければよい.
アノテーションやグリッドの幅はデフォルトだと自動で決まるが,指定する方法がやや独特であまり理解できていない. frameでアノテーションなどの間隔を指定するときに,数字の後に「p」をつけると指数表記({{< math >}} $10^n$ {{< /math >}})になる. そして幅の値を負にするとその指数の間隔(-nとすると{{< math >}} $10^n$ {{< /math >}}倍間隔)にできるっぽい. 正の値は1だと10倍間隔,2だとよくわからない,3だと10.1, 10.2,…のように10等分間隔に指定できる{{< math >}} $\cdots\cdots$ {{< /math >}}のか?
例)出力:図*※相互参照無効*
import numpy as np
import pygmt
x = np.linspace(1,1000000,100)
y = x**0.5
fig = pygmt.Figure()
with pygmt.config(
        MAP_FRAME_PEN='0.5p',
        MAP_GRID_PEN_SECONDARY='0.1p,#777777',
        MAP_GRID_PEN_PRIMARY='0.5p,black',
        ):
    fig.plot(
        x = x,
        y = y,
        pen = '1p,black',
        projection = ['X6cl/5cl'],
        region = 'e',
        frame = ['sxg3p','syg3p','pxa-1pg-1pf3p','pya-1pg-1pf3p'],
    )
fig.show()

{{< math >}} $\sqrt{x}$ {{< /math >}}の両対数軸プロット.
目盛り線(ticks)のスタイルの調整
with pygmt.config(
    MAP_TICK_LENGTH = '<length>',
    MAP_TICK_PEN = '<width>,<color>
    ):
    ...
ここでMAP_TICK_LENGTHを負の値にすると目盛りを内側に付けることができる. なお目盛り線の間隔はfig.basemap()などの中のframe=で指定する.
例)出力:図*※相互参照無効*
import pygmt
fig = pygmt.Figure()
with pygmt.config(
    MAP_FRAME_WIDTH = '1p',
    MAP_TICK_LENGTH = '-5p',
    MAP_TICK_PEN = '1p,red',
    ):
    fig.basemap(
        region = [0,1,0,1],
        projection = 'X4c',
        frame = ['neWS','af'],
    )
fig.show()

目盛り線(ticks)のスタイルの変更.
枠の見た目の調整
MAP_FRAME_TYPEの変更
地理系の投影図法のデフォルトの枠は縞々のフレーム(fancy)である. これを通常の線のフレーム (plain) や円い角の縞々枠 (fancy+) に変更できる. withの中で指定したframeに対して設定が適用される:
with pygmt.config(
    MAP_FRAME_TYPE = '<type>',
    ):
    fig.basemap(
        frame = <frame>,
        )
ただし以下の例のように,直交座標をfancyにすることはできないようである.
例)出力:図*※相互参照無効*
import pygmt
fig = pygmt.Figure()
with pygmt.config(
    MAP_FRAME_TYPE = 'plain',
    FONT = '8p',
):
    fig.basemap(
        region = [0,10,0,10],
        projection = 'M3c',
        frame = ['agf','+tM,plain'],
    )
    fig.shift_origin('4c','0c')
with pygmt.config(
    MAP_FRAME_TYPE = 'fancy+',
    FONT = '8p',
):
    fig.basemap(
        region = [0,10,0,10],
        projection = 'M3c',
        frame = ['agf','+tM,fancy+'],
    )
    fig.shift_origin('4c','0c')
with pygmt.config(
    MAP_FRAME_TYPE = 'fancy',
    FONT = '8p',
):
    fig.basemap(
        region = [0,10,0,10],
        projection = 'X3c',
        frame = ['agf','+tX,fancy'],
    )
fig.show()

地図の枠の変更.直交座標 (X) にはframeのタイプの指定は反映されない.
枠線のスタイル
with pygmt.configを使い,with構文内で枠線を作成するメソッドを使用してスタイルを変更できる.
with pygmt.config(
    MAP_FRAME_PEN = '<width>, <color>'):
    ...
地図ではなく普通のグラフにも使える.
枠線の太さだけを変更したい場合は次のようにする.
with pygmt.config(
    MAP_FRAME_WIDTH = <width>):
    ...
しかし地図ではない普通のグラフではこれは動作しなかった. 枠が「fancy」ではない場合はMAP_FRAME_PENで指定するのが良さそう.
グリッド・目盛りの共通設定
度分秒による指定
    frame = 'a<度>d<分>m<秒>s...'
点や描画範囲 (region) などの座標(第*※相互参照無効*節)の場合とは異なり, frameにおけるグリッドや目盛りの間隔の設定で度分秒を使うには「d/m/s」いずれかの単位を付す.
平行移動
グリッドや目盛りの位置は平行移動できる. 例えばデフォルトでは[0,10,20,…]の位置にグリッドが描かれる場合であっても, [5,15,25,…]のようにグリッドの位置を指定することができる.
    frame = '<agf>+<平行移動量>'
すなわち,最後に「+<数値>」を付すことで任意の量だけグリッドや目盛りを移動できる.
<注意>
アノテーションを小数表記にした地図(cf. 第*※相互参照無効*節)および直交座標(X)のグラフにのみ適用可能なようである.
第*※相互参照無効*節にある度分秒表記とは相性が悪いようで, 正常に動作しない(バグ? 仕様?). 移動が適用されなかったり,移動してもアノテーションの「分」以下の数字が切り捨てられて表示されたりする.
例)出力:図*※相互参照無効*
import pygmt
fig = pygmt.Figure()
with pygmt.config(
    MAP_TICK_PEN = '0.5p',
    MAP_GRID_PEN = '2p,black,solid',
    FORMAT_GEO_MAP = 'ddd.x'
    # FONT = '8p',
    ):
    # default
    fig.coast(
        shorelines = '0.5p',
        land = '#b0ffdd',
        water = '#b0ddff',
        region = '133:30/137:30/33/37',
        projection = 'M3c',
        frame = ['xa1g1f0.5','ya1g1f0.5']
    )
    fig.shift_origin('4.5c')
    # shifted
    fig.coast(
        shorelines = '0.5p',
        land = '#b0ffdd',
        water = '#b0ddff',
        region = '133:30/137:30/33/37',
        projection = 'M3c',
        frame = ['xa1g1f0.5+0.5','ya1g1f0.5+0.5']
    )
fig.show()

グリッド・目盛りの平行移動.左がデフォルト位置,右が0.5°平行移動した位置.
地図のregionの取得
fig.region
regionのリストが返ってくる.
使い時はあまりなさそうだが, 作成したFigureのregionをあとから取得できる.