蛇使いな彼女BLOG
【第76回】 グラフ編#3 記号の文字化防止表示 ~グラフ文字化けでハマった時のお話~
2023.01.06
新年明けましておめでとうございます。
皆様、今年の干支はうさぎですね!
うさぎはぴょんぴょん跳ねることから“飛躍”、“向上” の象徴と言われているそうですよ 🐇
そして今年の環境システムのカレンダー下部に描かれたイラストはうさぎではなく(笑)、船でも商材でもなく、カエルと猫です!
ヘビカノ推しありがとうございます!
モトハシも向上心を持って努力を続けていこうと思います。
本年度もどうぞよろしくお願い致します。
さて、今日の話題はグラフで特殊記号を表示する方法です。
私もPython、matplotlibを使いだしてから今日まで知らなかったのですが、特殊文字にもきちんとフォントがあって、それは「stix」と呼ばれるそうです。
数学的シンボルとアルファベット全般に対応したフォントで、「Tex」と呼ばれる文章整形システムで処理して特殊文字を表示します。
エクセルやワードの数式に当たる処理ですね。
Matplotlibには独自のTexエンジンが付いているため、stixフォントの別途インストールは不要です。
Matplotlibガイドラインの文章項目にも
Mathtext can use DejaVu Sans (default), DejaVu Serif, the Computer Modern fonts (from (La)TeX), STIX fonts (which are designed to blend well with Times), or a Unicode font that you provide.
日本語翻訳→「Mathtext では、DejaVu Sans (デフォルト)、DejaVu Serif、Computer Modern フォント ((La)TeX から)、STIXフォント (Times とうまく調和するように設計されています)。
またはユーザーが提供する Unicode フォントを使用できます。」
と記載があるので、どうやらmatplotlib, seabornのデフォルトフォントであるサンセリフ体のDejaVu Sansや、セリフ体ならDejaVu Serif、Timesなどでうまくシンボルが表示されるように設計されているのですね!
特殊文字を表示させたいとき文字化けしてしまう箇所については、通常matplotlibでアクティブになっているフォントの一部をstix(TeX)に置き換えて表示させると改善されるという事です。
そして逆に、rcParams でフォントファミリーをDejaVu Sansに設定していれば、mathtextのデフォルトがDejaVu Sansになっている為、わざわざstixフォントを使用することなく、特殊文字が反映される(文字化けが防げる)という仕組みになっています!
(システムとして完成されてるからフォント弄るな!って事ですね(笑) 開発した人すごい)
フォントにこだわり無いからなるべく文字化けを防ぎたい!という人には、
rcParams[‘font.family’]= ‘DejaVu Sans’
rcParams[‘mathtext.fontset’]= ‘dejavusans’
とコードに書き加えて、DejaVu Sans(デフォルト)を適応すると良いです↑。(cmとComputer Modernの組み合わせでもOK)
このフォント設定を行うと、これ以下のややこしい記事を見なくても殆どの文字化けを防げます。(笑)
stixフォントを使用する場合、rcParam[mathtext.fontset]で使用できるフォントセットキーワードは['dejavusans', 'dejavuserif', 'cm', 'stix', 'stixsans', 'custom']の6つです。
(※cmというフォントはComputer Modernの略です。)
このリストを見る限り、上記で説明したようなmathtextとフォントファミリーの設定のみで特殊文字の表示が概ね機能するのは、モトハシが試した限りDejavu(今回はsansのみ検証。serifの方は試していませんが
おそらく機能しそう?)と cmです。
それ以外のキーワードとフォントの関係については結構曖昧でそれぞれ、stixはTimes(セリフのロマン体)フォントに馴染むような設計をされていますし、stixsansはサンセリフに設計されています。
そのほか、customはmathtextを通常のテキストと同じように見せる為に用意されたキーワードで、この効果を適応させるには、mathtext のフォントパラメータとして'mathtext.rm'の他、'mathtext.it'、'mathtext.bf'なども必要に応じて表示させたいフォントに変更する必要があるそうです。
mathtext.fontsetでstix, stixsans, customのいずれかを選択した場合は、$マークで囲った領域に特殊記号やシンボルの名称を入力してフォントを出力します。(シンボル名称についてはガイドラインに記載があります)
rcParamsで、 mathtext.fontset :stix、font.family:Times New Romanを設定した条件で以下のように特殊記号を表示すると・・・
↓
この場合「※」と「▽」はmathtextで「℃αδ」は通常テキスト(Times New Roman)で表示されます。Times用に設計されているだけあって全体としてはうまくなじんでますね。
次に、mathtext.fontset : custom 、font.family:Times New Romanの条件下では、シンボルのフォント(stix(Tex)表記に関するフォント)設定が可能となるので、下図のように試しにmathtext.rmのパラメータを IPAexGothic(デフォルトは確かsans)に設定して表示すると、
「¥n」で改行する以前のテキストは通常テキストと同じTimes New Romanなので文字化けしていますが、改行後の$~$で囲ったmathtextと、mathrm{}で定義した日本語テキストはこの部分だけフォントが変更され、文字化けなしで表示が可能です。
↓
おお~!うまく表示されました。
mathtext優秀です!
このとき、改行前のただのテキストはTimes New Roman。mathrm{}に内包されているテキストはIPAexGothic、それ以外のmathtextはstixっぽいフォントになっています。(mathtext.rm のデフォルトsansはmathtext.fontsetの値によって変化しないという事かもしれませんが、もしかしたらfont.familyに影響を受けるのかな?とも思いました。)
今日まで文字化けとフォントについてご紹介しましたが、深掘りすればするほどデフォルトのサンセリフフォントでうまく動くように設計されている事が分かりました(笑)
今回作業に手間取った時間でまた一つ賢くなったと信じます。
では皆様良いお年をお過ごしください(^o^)