PyGMTにおけるフォント指定¶
GMTではあらかじめ40種弱のフォントが指定されており,コマンドラインの gmt text -L によりその一覧を出力することができます.以下はその一部です.
| フォント番号 | 名前 |
|---|---|
| 0 | Helvetica |
| 1 | Helvetica-Bold |
| 2 | Helvetica-Oblique |
| 3 | Helvetica-BoldOblique |
| 4 | Times-Roman |
| 5 | Times-Bold |
| 6 | Times-Italic |
| 7 | Times-BoldItalic |
| 8 | Courier |
| 9 | Courier-Bold |
| 10 | Courier-Oblique |
| 11 | Courier-BoldOblique |
| . | (中略) |
| 35 | Ryumin-Light-EUC-H |
| 36 | Ryumin-Light-EUC-V |
| 37 | GothicBBB-Medium-EUC-H |
| 38 | GothicBBB-Medium-EUC-V |
これらのフォントは,たとえば fig.text() モジュールの font オプションに名前あるいは番号で,
font = '12p,Times-Italic,Black'や
font = '10p,8,Black'のように指定することができます.
また,軸ラベルなどの任意の文字列に対して, @%(フォント番号)% と @%% で囲まれた文字列を指定のフォント番号で表示できます.次の図はアルファベットを表示可能なすべてのフォントを使った例です.ただし12 Symbolだけはギリシャ文字のアルファベットになります.
import pygmt
fig = pygmt.Figure()
fig.basemap(projection='X16c/10c', region=[0, 16, 0, 10],
frame = ['WSen+t@%0%0 Helvetica@%%',
'xaf+l@%1%1 Helvetica-Bold@%%',
'yaf+l@%2%2 Helvetica-Oblique@%%'])
fig.text(x=0.5, y=9.5, justify='LM', font='12p,4,Black', text='3 Helvetica-BoldOblique')
fig.text(x=0.5, y=9.0, justify='LM', font='12p,4,Black', text='4 Times-Roman')
fig.text(x=0.5, y=8.5, justify='LM', font='12p,5,Black', text='5 Times-Bold')
fig.text(x=0.5, y=8.0, justify='LM', font='12p,6,Black', text='6 Times-Italic')
fig.text(x=0.5, y=7.5, justify='LM', font='12p,7,Black', text='7 Times-BoldItalic')
fig.text(x=0.5, y=7.0, justify='LM', font='12p,8,Black', text='8 Courier')
fig.text(x=0.5, y=6.5, justify='LM', font='12p,9,Black', text='9 Courier-Bold')
fig.text(x=0.5, y=6.0, justify='LM', font='12p,10,Black', text='10 Courier-Oblique')
fig.text(x=0.5, y=5.5, justify='LM', font='12p,11,Black', text='11 Courier-BoldOblique')
fig.text(x=0.5, y=5.0, justify='LM', font='12p,12,Black', text='12 Symbol')
fig.text(x=0.5, y=4.5, justify='LM', font='12p,13,Black', text='13 AvantGarde-Book')
fig.text(x=0.5, y=4.0, justify='LM', font='12p,14,Black', text='14 AvantGarde-BookOblique')
fig.text(x=0.5, y=3.5, justify='LM', font='12p,15,Black', text='15 AvantGarde-Demi')
fig.text(x=0.5, y=3.0, justify='LM', font='12p,16,Black', text='16 AvantGarde-DemiOblique')
fig.text(x=0.5, y=2.5, justify='LM', font='12p,17,Black', text='17 Bookman-Demi')
fig.text(x=0.5, y=2.0, justify='LM', font='12p,18,Black', text='18 Bookman-DemiItalic')
fig.text(x=0.5, y=1.5, justify='LM', font='12p,19,Black', text='19 Bookman-Light')
fig.text(x=0.5, y=1.0, justify='LM', font='12p,20,Black', text='20 Bookman-LightItalic')
fig.text(x=0.5, y=0.5, justify='LM', font='12p,21,Black', text='21 Helvetica-Narrow')
fig.text(x=8.5, y=9.5, justify='LM', font='12p,22,Black', text='22 Helvetica-Narrow-Bold')
fig.text(x=8.5, y=9.0, justify='LM', font='12p,23,Black', text='23 Helvetica-Narrow-Oblique')
fig.text(x=8.5, y=8.5, justify='LM', font='12p,24,Black', text='24 Helvetica-Narrow-BoldOblique')
fig.text(x=8.5, y=8.0, justify='LM', font='12p,25,Black', text='25 NewCenturySchlbk-Roman')
fig.text(x=8.5, y=7.5, justify='LM', font='12p,26,Black', text='26 NewCenturySchlbk-Italic')
fig.text(x=8.5, y=7.0, justify='LM', font='12p,27,Black', text='27 NewCenturySchlbk-Bold')
fig.text(x=8.5, y=6.5, justify='LM', font='12p,28,Black', text='28 NewCenturySchlbk-BoldItalic')
fig.text(x=8.5, y=6.0, justify='LM', font='12p,29,Black', text='29 Palatino-Roman')
fig.text(x=8.5, y=5.5, justify='LM', font='12p,30,Black', text='30 Palatino-Italic')
fig.text(x=8.5, y=5.0, justify='LM', font='12p,31,Black', text='31 Palatino-Bold')
fig.text(x=8.5, y=4.5, justify='LM', font='12p,32,Black', text='32 Palatino-BoldItalic')
fig.text(x=8.5, y=4.0, justify='LM', font='12p,33,Black', text='33 ZapfChancery-MediumItalic')
fig.show(crop=0.5, width=800)GMTのデフォルトで設定される一連のフォントのなかに,
35: Ryumin-Light-EUC-H
36: Ryumin-Light-EUC-V
37: GothicBBB-Medium-EUC-H
38: GothicBBB-Medium-EUC-Vという4つのフォントがあります.35と36はリュウミン(明朝体),37と38はゴシック体なのですが,文字コードがEUCのため,UTF-8コードが標準のPythonではそのまま使うことができません.
また,PyGMTのバックエンドであるGMTが画像として最初に生成するPostScript形式のファイルをPNGやPDF形式に変換する(fig.show()コマンドでも内部でそのような変換が走っています)際に用いられる ghostscript というプログラムがあるのですが,日中韓のフォント(CJKフォント)を用いるためには+アルファの手当が必要で,condaでPyGMTと一緒にインストールされたghostscriptでは(筆者が試した限り)うまくいかないようでした.
そこで,PyGMTで日本語を扱うためには,
日本語フォントの準備
ghostscriptを別途導入
日本語フォント利用のための設定
が必要です.ところが,フォントのインストール先や扱いがOSによって異なるため,あらゆる環境で統一的にうまくいく方法はなさそうです.以下では筆者環境(Ubuntu 22.04.4 LTS)で動作した方法を標準として紹介し,macOSについて後から補足します.Ubuntuの派生Linux(Linux Mintなど)はほとんど同じように動くと思われますが,RedHat系ではファイルの置き場が大きく異なる可能性があります.
Ubuntu Linuxにおける設定¶
1. フォントのインストール¶
デスクトップ版のOSを導入していたらおそらくインストール済みですが,デフォルトの Takao フォントを用います.
$ sudo apt install fonts-takaoこのフォントは
/usr/share/fonts/truetype/takao-gothic/TakaoPGothic.ttf/usr/share/fonts/truetype/takao-mincho/TakaoPMincho.ttf
にインストールされます.
2. システムに ghostscript を導入¶
$ sudo apt install ghostscript poppler-dataGhostscriptのバイナリは /usr/bin/gs に配置されます.
3. cidfmap ファイルの確認¶
/var/lib/ghostscript/fonts/cidfmap を閲覧し,以下の行があることを確認してください.
/Japanese-Mincho-Regular << /FileType /TrueType /Path (/usr/share/fonts/truetype/fonts-japanese-mincho.ttf) /SubfontID 0 /CSI [(Japan1) 4] >> ;
/Japanese-Gothic-Regular << /FileType /TrueType /Path (/usr/share/fonts/truetype/fonts-japanese-gothic.ttf) /SubfontID 0 /CSI [(Japan1) 4] >> ;
/Ryumin-Light /Japanese-Mincho-Regular ;
/GothicBBB-Medium /Japanese-Gothic-Regular ;cidfmap ファイルの先頭列の名前がPyGMTにおけるフォント名の基本部分になります.
4. PSL_custom_fonts.txt の作成¶
ユーザーのホームディレクトリ直下の .gmt/PSL_custom_fonts.txt ファイルを編集し(なければ作る).以下の2行を追加します.
Ryumin-Light-UniJIS-UTF8-H 0.700 1
GothicBBB-Medium-UniJIS-UTF8-H 0.700 1第1列の Ryumin-Light と GothicBBB-Medium が cidfmap の記述の第1列に存在することが重要です.
5. フォント設定状況の確認¶
GMTのインストールされている環境のターミナルから,コマンドラインで gmt text -L を実行して,フォント一覧を確認します.
$ gmt text -L
gmt text [core] 6.6.0 [64-bit] [MP] - Plot or typeset text
(中略)
35: Ryumin-Light-EUC-H
36: Ryumin-Light-EUC-V
37: GothicBBB-Medium-EUC-H
38: GothicBBB-Medium-EUC-V
39: Ryumin-Light-UniJIS-UTF8-H
40: GothicBBB-Medium-UniJIS-UTF8-H
------------------------------------
For additional fonts, see "Using non-default fonts with GMT" in the documentation.この場合は39-40番に今回追加したフォントが表示されるはずです.ここまでで設定完了です.
6. gs_path の明示指定¶
PyGMTで作られた画像オブジェクト fig は,内部的にはPostScript形式の画像を持っており,fig.show() や. fig.savefig(), fig.ps2raster() などの表示や画像保存のメソッドを呼び出した際に,外部ツールとして Ghostscript を呼び出して png や pdfといった画像に変換しているようです.ここで行った設定を利用するには,PyGMTの依存関係として自動的にconda環境にインストールされたghostscriptではなく,手順2で手動インストールしたほうのghostscriptを使う必要があります.
そこで,gs_path="/usr/bin/gs" というオプションを .show(), .savefig(), .ps2raster() に指定します.これで利用するghostscriptを指定し,日本語フォントを正しく読み込むことができるようになります.
macOSの場合¶
Ubuntuと同様に,conda 外で ghostscript をインストールして使うのですが,
cidfmapの場所が異なるmacOSのデフォルトのフォントが(筆者の試した限り)うまく読み込めない
という問題があります.そこで,ユーザー領域に追加フォントを導入して,それを利用する方向で対策してみます.
1. フォントのインストール¶
モリサワのユニバーサルデザインフォント BIZ UD明朝 とBIZ UDゴシック がGoogle Fontsからダウンロードできるので,まずはこれらをインストールします.ダウンロードしたフォントファイルをダブルクリックしてインストールボタンを押すと,/Users/ユーザー名/Library/Fonts 以下にファイルが配置されるはずです.
2. システムに ghostscript を導入¶
macOSのパッケージ管理システム Homebrew を用いてインストールします.もしHomebrewをインストールしていなかったら https://brew.sh の解説の通りにインストールし,ターミナルから
$ brew install ghostscriptによりインストールします.GhostscriptのバイナリはHomebrewのデフォルト設定なら /opt/homebrew/bin/gs に配置されるはずです.
3. cidfmap ファイルの編集¶
/opt/homebrew/share/ghostscript/Resource/Init/cidfmap を適当なテキストエディタで編集し,以下の行を追記します.ただし,「ユーザー名」はご自身のmacOSのユーザー名に変更してください.
/Japanese-Mincho-Regular << /FileType /TrueType /Path (/Users/ユーザー名/Library/Fonts/BIZUDMincho-Regular.ttf) /SubfontID 0 /CSI [(Japan1) 2] >> ;
/Japanese-Gothic-Regular << /FileType /TrueType /Path (/Users/ユーザー名/Library/Fonts/BIZUDGothic-Regular.ttf) /SubfontID 0 /CSI [(Japan1) 2] >> ;
/Ryumin-Light /Japanese-Mincho-Regular ;
/GothicBBB-Medium /Japanese-Gothic-Regular ;以下,手順 4・手順 5はUbuntuの場合と同じです..show(), .savefig(), .ps2raster() に指定すべき gs_path オプションの値はLinuxと異なり,gs_path="/opt/homebrew/bin/gs" です.
日本語フォントの指定¶
ここまでの設定ができていれば,本ページ冒頭で説明したものと同じ要領で,
39: Ryumin-Light-UniJIS-UTF8-H
40: GothicBBB-Medium-UniJIS-UTF8-H
のフォントをそれぞれ使えます.名前が長いので番号で使うのが簡単でしょう.39番が明朝体,40番がゴシック体です.
以下はmacOS環境で実際に日本語を用いた地図の例です.
import pygmt
fig = pygmt.Figure()
with pygmt.config(
FONT_ANNOT_PRIMARY = '12p,Helvetica,black',
FONT_ANNOT_SECONDARY = '11p,Helvetica,black',
FONT_LABEL = '14p,Helvetica,black',
FONT_TITLE = '14p',
MAP_GRID_PEN_PRIMARY = '0.25p,30/30/30,.',
MAP_FRAME_TYPE = 'plain',
FORMAT_GEO_MAP = 'DF',
FORMAT_FLOAT_OUT = '%.1f',
PS_IMAGE_COMPRESS = 'none',
PS_LINE_CAP = 'round',
PS_LINE_JOIN = 'round'
):
fig.coast(projection='M12c', region=[139.7, 141.8, 40.3, 41.6],
resolution='full', area_thresh = 50,
shorelines = 'thinnest,black', water = '250',
frame = ['WSen+t@%40%青森県の県庁・市庁所在地@%%', #<-- @%40% .. @%% でフォント指定
'xaf', 'yaf'])
fig.plot(x = [140.740005, 140.464008, 141.488404, 140.594547, 140.446118,
141.205910, 141.369093, 141.183174, 140.380195, 140.567123],
y = [40.824440, 40.602965, 40.512278, 40.642608, 40.807835,
40.612703, 40.683078, 41.292835, 40.808836, 40.583742],
style = 'c0.2c', fill='150/100/250', pen='thin,black')
fig.text(x = [140.740005, 140.464008, 141.488404, 140.594547, 140.446118,
141.205910, 141.369093, 141.183174, 140.380195, 140.567123],
y = [40.824440, 40.602965, 40.512278, 40.642608, 40.807835,
40.612703, 40.683078, 41.292835, 40.808836, 40.583742],
offset = '0c/-0.2c',
font='8p,40,Black', #<-- 日本語フォントを指定
text = ['青森', '弘前', '八戸', '黒石', '五所川原',
'十和田', '三沢', 'むつ', 'つがる', '平川'],
justify=['CT','RT','CT','LT','LT','CT','CT','CT','RT', 'CT'],
fill='white@20%', clearance='0.05')
fig.show(gs_path='/opt/homebrew/bin/gs', dpi=600, width=800)