2013年2月22日金曜日

Python,Matplotlibでギリシャ文字出力方法2

概要

matplotlibのギリシャ文字出力方法については以前書いたが、Tex形式で出力する方法('$\mu$'など)とフォントの保有しているギリシャ文字をUnicodeから指定する方法(u'\u03bc'等)がある。
使用するフォントにも依るが、両者でグラフの見た目が結構変わる。
特にArialやそれ系のフォント(Helvetica欲しい……)等、サンセリフ体のものを使う場合、Tセリフ体の文字が出力されるためTex方式では、ギリシャ文字に対してそれ以外の英数字が浮いてしまう。
気にならなければ構わないのだが、個人的にはグラフ全体に同一のフォントを使用したほうが統一感が出て良いと思う。
まあ、Times New Romanとかそれ系のセリフフォント(Times欲しい……)を使うならそれほど違和感はないかもしれないが、これらのフォントにもギリシャ文字が同梱されているわけで、それを使ったほうがやはり統一感が出て美しいのではないかと思う。

学会によってはギリシャ文字はSymbolを使えというところもあるようなので、その場合は仕方ないし、ギリシャ文字はSymbolじゃないとという人もいるのかもしれない。
ただ、グラフのフォントをIllustratorなどを使って差し替える場合、Symbolを使用していると一括変換ができないが、Unicodeを使えば変換先のフォントがコードに対応したフォントを持っていれば問題なく変換できてしまうというメリットがある。

比較

ギリシャ文字をTex形式とUnicode形式で出力したグラフを作成した。英数字のフォントをArialとした場合とTimes New Romanとした場合の結果を以下に示す。

Arial

Arial、ギリシャ文字はUnicode形式

Arial、ギリシャ文字はTex形式

Times New Roman

Times New Roman、ギリシャ文字はUnicode形式

Times New Roman、ギリシャ文字はTex形式

考察

Arial等のサンセリフフォントを利用する場合、ギリシャ文字をTex形式で出力するとセリフ体とサンセリフ体が1つのグラフに混在することになる。また、Tex形式で出力したデータのギリシャ文字のフォントはCmmi10及びCmr10となる。これらは通常Illustratorで編集することができない。そのため、Illustratorで加工する場合、自分で適宜Symbolにするなりしなければならない事になる。(ただし、これらのTexフォントをIllustratorで扱えるようにする方法もあるらしい) matplotlibはグラフの描画機能が優秀であるため、Illustratorを介さずに十分な品質のグラフを直接出力することが可能だが、フォントを埋め込む場合はpdf形式しか出力できない(epsだとフォントがアウトライン化されてしまう。何とかepsにフォントを埋め込む方法はないかは調査中)。そのため、面倒なくTexに埋め込むにはIllustratorでeps形式に出力し直さなければならない。Unicode方式ではそのまま保存できるが、Tex方式ではTexのフォントをIllustratorで扱えるようにしないと、フォント調整に一手間かかることになる。 一方で、Unicode形式の場合、出力したい文字のUnicodeを一々調べねばならず面倒である。また、グラフ中に数式を描きたい場合はやはりTex形式の方が優れているように思う。 どちらの方法も一長一短であるという毒にも薬にもならない戯言が結論になるだろうか。

付録

グラフ作成に使用したデータとPythonコードを以下に示す。なお、Pythonコードはあちこちのホームページやブログを参考にさせていただいているが、どこがどこを参考にしたのか全く把握できないため、特に引用の記載はない。誠に申し訳ない。

データ:


sample.txt
# This is a sample data
0 0 5
0.314159265 2.938926261 4.484011233
0.628318531 4.755282581 0.71019761
0.942477796 4.755282581 0.71019761
1.256637061 2.938926261 4.484011233
1.570796327 6.12574E-16 5
1.884955592 -2.938926261 -1.39384129
2.199114858 -4.755282581 -8.800367553
2.513274123 -4.755282581 -8.800367553
2.827433388 -2.938926261 -1.39384129
3.141592654 -1.22515E-15 5
3.455751919 2.938926261 4.484011233
3.769911184 4.755282581 0.71019761
4.08407045 4.755282581 0.71019761
4.398229715 2.938926261 4.484011233
4.71238898 1.83772E-15 5
5.026548246 -2.938926261 -1.39384129
5.340707511 -4.755282581 -8.800367553
5.654866776 -4.755282581 -8.800367553
5.969026042 -2.938926261 -1.39384129
6.283185307 -2.4503E-15 5

Pythonコード

#コメントは#マークを使うか"""hogehoge"""とする.

#ライブラリをインポート
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
#import datetime #ここらへんのパッケージは昔必要になったことがあったようななかったような
#import matplotlib.colors as colors
#import matplotlib.finance as finance
#import matplotlib.dates as mdates
#import matplotlib.ticker as mticker
#import matplotlib.mlab as mlab
#import matplotlib.font_manager as font_manager


pi = np.pi # 円周率が必要な場合はnumpy(インポート設定からnp.~とする),このように出力できる
e = np.e # 自然対数とかも出力可能
###############################################################################
#                               Graph Setting                                 #
###############################################################################
###############################################################################
mpl.rcParams['font.family'] = 'Arial' #使用するフォント名
mpl.rcParams['pdf.fonttype'] = 42 #このおまじないでフォントが埋め込まれるようになる
params = {'backend': 'ps', # バックエンド設定
          'axes.labelsize': 8, # 軸ラベルのフォントサイズ
          'text.fontsize': 8, # テキストサイズだろう      
          'legend.fontsize': 8, # 凡例の文字の大きさ
          'xtick.labelsize': 8, # x軸の数値の文字の大きさ
          'ytick.labelsize': 8, # y軸の数値の文字の大きさ
          'text.usetex': False, # 使用するフォントをtex用(Type1)に変更
          'figure.figsize': [10/2.54, 6/2.54]} # 出力画像のサイズ(インチなので2.54で割る)
mpl.rcParams.update(params)

###############################################################################
#                                 Data Input                                  #
###############################################################################
###############################################################################
#データ読み込みにはnumpyのloadtxtを使用すると便利
filename = "sample.txt"
data = np.loadtxt(filename, #ファイルの名前
                  skiprows=1, #この場合ファイルの一行目をスキップする
                  dtype={'names':('data1',
                                  'data2',
                                  'data3'),
                        'formats':('f8',
                                   'f8',
                                   'f8'
                               )})

###############################################################################
#                                 Make Graph                                  #
###############################################################################
###############################################################################
plt.rc('axes', grid=True)#
plt.rc('grid', color='0.8', linestyle='-.', linewidth=0.5)#
bs = plt.figure(facecolor='white')
base_ax = plt.axes([0.15,0.15,0.75,0.75])
ax1 = plt.plot(data['data1'], data['data2'], 'ro-', label='Sample1')#散布図の描画.凡例のラベル設定はここで行う
ax2 = plt.plot(data['data1'], data['data3'], 'bs--', label='Sample2')
lx = plt.xlabel(u'x line [\u03bcm]')#x軸のラベル
ly = plt.ylabel(u'y line [\u03bcm]')#y軸のラベル
tx = plt.xticks(np.arange(0, 2.1*pi, 0.5*pi),#np.arange(0, 2*pi, 0.5*pi)とすると2*piが含まれない
                [u'0',u'0.5\u03C0',u'\u03C0',u'1.5\u03C0',u'2\u03C0']) #xラベルの設定
                #$\pi$表記でTex形式出力も可能
limx = plt.xlim(0, 2*pi) # xの範囲
leg = plt.legend(loc='best', shadow=True, fancybox=True)#凡例出力
leg.get_frame().set_alpha(0.5)#凡例を半透明にする
plt.savefig('sample.pdf')# PDF形式で保存する場合,フォントが埋め込まれる
plt.savefig('sample.eps')# EPS形式で保存する場合,フォントはアウトライン化される
plt.savefig('sample.png', dpi=100)# png形式ではdipの調整ができる.デフォルトでは80だったはず
plt.show()#グラフ出力.最後に持ってくる(savefigがうまく動かなかったりするため)

0 件のコメント:

コメントを投稿