日本語フォントの利用#

Danger

本ページで解説している内容の再現性はOSやソフトウェアのインストール状況に依存する可能性があります.また,これが最良の方法とは限りません.より良い方法をご存知のかたはぜひ Issues でお知らせください.

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)
_images/ad9bf56235f2d47759678f9ff7750812dc62e23b03e6fcf3f173a2b66cf62054.png

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ではそのまま使うことができません.

Note

UTF-8が普及した現在はあまり使われなくなりましたが,昔は日本語を表す文字コードにWindows系でよく用いられるShift-JISと,Unix系で用いられたEUCが混在していて,互いに変換が必要でした.

また,PyGMTのバックエンドであるGMTが画像として最初に生成するPostScript形式のファイルをPNGやPDF形式に変換する(fig.show()コマンドでも内部でそのような変換が走っています)際に用いられる ghostscript というプログラムがあるのですが,日中韓のフォント(CJKフォント)を用いるためには+アルファの手当が必要で,condaでPyGMTと一緒にインストールされたghostscriptでは(筆者が試した限り)うまくいかないようでした.

そこで,PyGMTで日本語を扱うためには,

  1. 日本語フォントの準備

  2. ghostscriptを別途導入

  3. 日本語フォント利用のための設定

が必要です.ところが,フォントのインストール先や扱いが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-data

Note

poppler-data は旧 gs-cjk-resource に代わるもので,日中韓のフォント利用に関するファイルがインストールされるようです.

Ghostscriptのバイナリは /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 ;

Tip

書式を真似て,第1列のフォント名と /Path () を変えることで新たなフォントを追加することもできます(IPAexフォントで動作確認済).ただし,拡張子が .ttc のTrueType Collection形式は読めないようです.

Note

Ubuntuでは /usr/share/fonts/truetype/fonts-japanese-mincho.ttf/etc/alternatives/fonts-japanese-mincho.ttf を介して Takao明朝 /usr/share/fonts/truetype/takao-mincho/TakaoPMincho.ttf に紐づけられています.ゴシックも同様です.

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-LightGothicBBB-Mediumcidfmap の記述の第1列に存在することが重要です.

Tip

上記設定ファイルはユーザーごとに設定する必要がありますが,PyGMTを仮想環境ごとシステムにインストールしている場合など複数ユーザーに同時に効かせたいときには, (condaインストール先)/envs/(conda仮想環境名)/share/gmt/PSL_custom_fonts.txt に設定を書いても有効となります.

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番に今回追加したフォントが表示されるはずです.ここまでで設定完了です.

macOSの場合#

Ubuntuと同様に,conda 外で ghostscript をインストールして使うのですが,

  • cidfmap の場所が異なる

  • macOSのデフォルトのフォントが(筆者の試した限り)うまく読み込めない

という問題があります.そこで,ユーザー領域に追加フォントを導入して,それを利用する方向で対策してみます.

1. フォントのインストール#

モリサワのユニバーサルデザインフォント BIZ UD明朝BIZ UDゴシック がGoogle Fontsからダウンロードできるので,まずはこれらをインストールします.ダウンロードしたフォントファイルをダブルクリックしてインストールボタンを押すと,/Users/ユーザー名/Library/Fonts 以下にファイルが配置されるはずです.

Tip

後述の Homebrew をつかって

$ brew install font-biz-udgothic font-biz-udmincho

としてもOKです.

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の場合と同じです.

日本語フォントの指定#

ここまでの設定ができていれば,本ページ冒頭で説明したものと同じ要領で,

  • 39: Ryumin-Light-UniJIS-UTF8-H

  • 40: GothicBBB-Medium-UniJIS-UTF8-H

のフォントをそれぞれ使えます.名前が長いので番号で使うのが簡単でしょう.39番が明朝体,40番がゴシック体です.

Important

日本語フォントを使った場合,fig.show(), fig.savefig(), fig.psconvert() メソッドには,すべて gs_path= オプションにシステムのGhostScriptのバイナリをフルパスで指定してください.Ubuntuの場合は gs_path="/usr/bin/gs", macOSの場合には gs_path="/opt/homebrew/bin/gs" です.

以下は実際に日本語を用いた地図の例です.

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)
_images/d8ca2f696d9a26338709f69a5cf5f1dc92a37e205864cde76f124e178201267d.png

Tip

PyGMTの fig.show() メソッドは,PostScript形式で作成されていた図をラスター画像にしてJupyter Notebookに表示します.その際 dpi=150 の解像度が仮定されているようです.多くの場合には困りませんが,日本語で細かい字を表示するとガタツキが気になる場合があります.そのようなときには,上記の例のように dpi=300からdpi=600 程度を指定すると滑らかになります.当然ですが埋め込まれる画像のファイルサイズは大きくなります.