matplotlib で白黒のグラフを描く際の設定

論文に載せるグラフは白黒のほうが見栄えが良い。それでなくても色は峻別不可能な人がいたりするから不便なことがある。

理想としては pylab.set_bw(True) みたいなことをするとそれ以降のすべての図が白黒になるといいのだけれど、残念ながらそのような関数は用意されていないらしい。color_cycle を変更する方法はある のだから、linestyle_cycle を変更する方法が用意されていてもおかしくないはずだが……。これができれば、color_cycle=['k'] として linestyle_cycle を変更すれば自動で白黒化できるのに。一応 簡単な解決策 みたいなのは提示されている。似た機能を盛り込んだらしい matplotlib の branch も存在する。Black and White mode を盛り込もうという提案もある。だれかやってくれませんかね。

plot

stackoverflow 先生 を参考に。変更点は pylab のみを使う(import matplotlib などとはしない)ようにしたこと。 setAxLinesBWsetFigLinesBW の中身は全く弄っていません。このファイルに hoge とか名前をつけて $PYTHONPATH に置き、使いたいときに from hoge import setFigLinesBW みたいなことをやって setFigLinesBW(pylab.gcf()) してやれば万事解決するのだと期待される。

import pylab

def setAxLinesBW(ax):
    """
    Take each Line2D in the axes, ax, and convert the line style to be
    suitable for black and white viewing.
    """
    MARKERSIZE = 3

    COLORMAP = {
        'b': {'marker': None, 'dash': (None,None)},
        'g': {'marker': None, 'dash': [5,5]},
        'r': {'marker': None, 'dash': [5,3,1,3]},
        'c': {'marker': None, 'dash': [1,3]},
        'm': {'marker': None, 'dash': [5,2,5,2,5,10]},
        'y': {'marker': None, 'dash': [5,3,1,2,1,10]},
        'k': {'marker': 'o', 'dash': (None,None)} #[1,2,1,10]}
        }

    for line in ax.get_lines():
        origColor = line.get_color()
        line.set_color('black')
        line.set_dashes(COLORMAP[origColor]['dash'])
        line.set_marker(COLORMAP[origColor]['marker'])
        line.set_markersize(MARKERSIZE)

def setFigLinesBW(fig):
    """
    Take each axes in the figure, and for each line in the axes, make the
    line viewable in black and white.
    """
    for ax in fig.get_axes():
        setAxLinesBW(ax)

xval = pylab.arange(100)*.01

pylab.plot(xval,pylab.cos(2*pylab.pi*xval))
pylab.plot(xval,pylab.cos(3*pylab.pi*xval))
pylab.plot(xval,pylab.cos(4*pylab.pi*xval))
pylab.plot(xval,pylab.cos(5*pylab.pi*xval))
pylab.plot(xval,pylab.cos(6*pylab.pi*xval))
pylab.plot(xval,pylab.cos(7*pylab.pi*xval))
pylab.plot(xval,pylab.cos(8*pylab.pi*xval))

pylab.savefig("colorDemo.eps")
setFigLinesBW(pylab.gcf())  # get current figure
pylab.savefig("bwDemo.eps")

histogram

白黒でヒストグラムを塗りつぶすとわけが分からなくなるので、histtype='step' を指定するのがポイント。ちなみに plot のときに使用した関数では白黒化できない。おそらく引かれる線が line ではない? コードの中身を見てはいないので詳しくはわからないけれども。

pylab.hist(x, histtype='step', color='k',
    linestyle='solid')  # 'dashed', 'dotted', 'dashdot'

ちょっと線が細いかな、というときは linewidth=2 を追加。

heatmap

使う頻度が低いので詳細は次回使った時にでも更新する。