[Python]matplotlib出力画像で日本語が文字化けする現象

Kazutoshi Shinoda 929views 更新:2016年4月19日

pythonのmatplotlibで日本語をタイトルや軸ラベルで使用するといわゆる豆腐になる現象に何度かはまったので二度と忘れないために投稿します。

以下のコードはフィッシャーの線形判別分析を実装したものです。

バージョンはpython2.7です。

# -*- coding:utf-8 -*-

'''
Created on 2016/04/19

@author: Pikachu
'''

import random as rd;
import numpy as np;
from matplotlib import pyplot as plt;

n = 600;
for j in range (1,6):
    alpha = (2*j-1)*0.1;
    x = [];
    for i in range(0,n):
        x.append(rd.random());
    x1s = [i for i in x if i < alpha];
    n1 = len(x1s);
    n2 = n - n1;

    x1_1 = [rd.gauss(2,1) for i in range(0,n1)];
    x1_2 = [rd.gauss(0,3) for i in range(0,n1)];

    x2_1 = [rd.gauss(-2,1) for i in range(0,n2)];
    x2_2 = [rd.gauss(0,3) for i in range(0,n2)];

    plt.clf();
    plt.figure(num = j);
    plt.scatter(x1_1, x1_2, marker = "o", c = "b", label = "y = 1");
    plt.scatter(x2_1, x2_2, marker = "x", c = "r", label = "y = 2");

    x3_2 = np.linspace(-12, 12, 7);
    x3_1 = [-1.0/4.0*np.log(alpha/(1.0-alpha)) for i in x3_2];
    plt.plot(x3_1, x3_2, "g-", label = u"決定境界");
    plt.title(u"線形判別分析の実装(α = "+str(alpha)+u")");
    plt.legend();

    plt.show();

何も対処せずにこのコードで画像を出力すると以下のようになります。

…とここで画像をアップしようとしたのですがhacknoteには画像をアップロードする機能がないらしいです。なんてこった

とにかく「線形判別分析」という文字列が「◽︎◽︎◽︎◽︎◽︎◽︎」となってしまいます。

なぜ日本語が文字化けするのかというと、matplotlibが日本語フォントを持たないためらしいです。

ではどうしたらいいのか・・・・


①日本語フォントをダウンロードしてくる

ここでは独立行政法人 情報処理推進機構が提供しているIPAフォントを利用させていただきます。

このサイトからフォントをダウンロードし、

適宜環境にあった場所にフォントファイルを移します。

僕の場合はmacなので、ipag.ttfを/Users/ユーザー名(Pikachu)/Library/Fonts/下に置きました。

②フォントを定義する

以下のコードを追加します。

from matplotlib.font_manager import FontProperties
fp = FontProperties(fname='/Users/ユーザー名/Library/Fonts/ipag.ttf');

③フォントを指定する。

日本語をtitleやlabelで使用する際、fontpropertiesオプションやpropオプションを用いて

上で定義したfpをフォントとして指定する。

# タイトルはfontproperties
plt.title(u"線形判別分析の実装(α = "+str(alpha)+u")", fontproperties = fp);
# 凡例はprop
plt.legend(prop = fp);

※凡例以外はfontpropertiesらしい。参考


これで晴れて日本語を表示できるようになりました。

ログイン / 新規登録してコメントする

このソースコードをストックして後で利用したり、作業に利用したソースコードをまとめることができます。

こちらもお役に立つかもしれません