[Matplotlib超入門:pyplot編]グラフの中で日本語を使おうPythonデータ処理入門

Matplotlibでグラフを描いても、日本語がうまく表示されないことがあります。その原因と、日本語を表示するいろいろな方法について見ていきましょう。

» 2025年07月18日 05時00分 公開
[かわさきしんじDeep Insider編集部]
「Pythonデータ処理入門」のインデックス

連載目次

本シリーズと本連載について

 本シリーズ「Pythonデータ処理入門」は、Pythonの基礎をマスターした人を対象に以下のような、Pythonを使ってデータを処理しようというときに便利に使えるツールやライブラリ、フレームワークの使い方の基礎を説明するものです。

 なお、【Matplotlib超入門:pyplot編】では以下のバージョンを使用しています。

  • Python 3.13
  • Matplotlib 3.10.3

 なお、以下ではMatplotlibのpyplotインタフェースやNumPy、pandasをインポートする以下の行を実行してあるものとします。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

お約束のコード

日本語のテキストを含んだグラフを表示してみよう

 まずは以下のコードを見てください。

def plot():
    plt.plot([1, 2, 3], [1, 4, 9])
    plt.title('グラフのタイトル')
    plt.xlabel('X軸')
    plt.ylabel('Y軸')
    plt.text(2, 5, '日本語のテキスト')
    plt.show()

plot()

日本語のテキストを含んだグラフの描画

 これはX軸とY軸のラベルや、タイトル、コメントを日本語で記したグラフを描画する関数plotを定義して、それを呼び出すものです。筆者の手元の環境でこれを実行したら、次のようになりました。

日本語がきちんと表示されなかった 日本語がきちんと表示されなかった
グラフの上には大量の警告も表示されているが、それらは省略する。

 うまく日本語が表示できていませんね。これはMatplotlibが日本語に対応していないからではなく、そのデフォルト設定では日本語には対応していないフォントがテキスト表示に使われるようになっているからです。

 Matplotlibでのグラフ周りのフォント設定はpyplot.rcParams属性に辞書の形で保存されています。主に使用するのは以下といえるでしょう。

  • rcParams['font.family']:フォントファミリーの指定。デフォルトでは'sans-serif'が設定されている
  • rcParams['font.sans-serif']:サンセリフ書体(装飾なし。日本語フォントでいうゴシック系)のフォントの指定

 これらのフォント設定を調べてみましょう。

font_family = plt.rcParams['font.family']
font_sans_serif = plt.rcParams['font.sans-serif']
font_serif = plt.rcParams['font.serif']
font_cursive = plt.rcParams['font.cursive']
font_fantasy = plt.rcParams['font.fantasy']
font_monospace = plt.rcParams['font.monospace']

print('family:', font_family)
print('sans serif:', font_sans_serif)
print('serif:', font_serif)
print('cursive:', font_cursive)
print('fantasy:', font_fantasy)
print('monospace:', font_monospace)

フォント設定の取得

 ここでは上に挙げた2つのフォント設定に加えて、セリフ系の(装飾のある)フォントを指定するrcParams['font.serif']、筆記体のようなフォントを指定するrcParams['font.cursive']、装飾が多めのフォントを指定するrcParams['font.fantasy']、等幅フォントを指定するrcParams['font.monospace']についても調べています(が、それらについてはここでは深く取り上げません)。

 実行結果を以下に示します。

フォント設定 フォント設定

 フォントファミリーは'sans-serif'になっているので、rcParams['font.sans-serif']の設定が使われると考えればよいでしょう。この場合は、rcParams['font.sans-serif']の値である['DejaVu Sans', 'Bitstream Vera Sans', ……, 'Avant Garde', 'sans-serif']というリストの中からシステムにインストールされているものが使われます(リストの前方にあるものが優先的に使われます)。そして、このリストに日本語の書体を持ったフォントがないので、先ほどのように文字表示がうまくいかなかったのです。

pyplot.rcParams属性によるフォントの設定

 ということは、日本語が表示されるようにMatplotlibを設定する一番簡単な方法は、rcParams['font.family']かrcParams['font.sans-serif']に日本語フォントを指定してやることです。自分が使っているシステムにインストール済みのフォントであれば、'Meiryo'などのように指定できます。

plt.rcParams['font.sans-serif'] = ['Meiryo']

サンセリフ書体としてMeiryo(メイリオ)を指定

 ここでやっているように、フォント名はリストの形で複数与えます。複数のフォントを指定する例を以下に示します(「pyplot.rcParams['font.family'] = ['sans-serif']」行はデフォルトの設定なので不要ですが、ここでは明示しています)。

plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Meiryo']

plot()

pyplot.rcParams['font.sans-serif']に「ヒラギノ丸ゴPro」と「メイリオ」を指定する例

 ここではmacOSにバンドルされている「ヒラギノ丸ゴPro」とWindowsでよく使われる「メイリオ」をpyplot.rcParams['font.sans-serif']に指定しています。macOSでこのコードを実行すると、次のように丸みを帯びたゴシック体でグラフのテキストが描画されます。

macOSで実行した結果ヒラギノ丸ゴProが使われている macOSで実行した結果ヒラギノ丸ゴProが使われている

 一方、Windowsでこれを実行した場合、「メイリオ」が使われるのでヒラギノ丸ゴProほどには丸みを帯びていない文字が使われます。

Windowsで実行した結果。メイリオが使われている Windowsで実行した結果。メイリオが使われている

 なお、Hiraginoフォントについては「Hiragino sans」というフォント名を指定することも可能です。これは(少なくとも筆者の手元の環境では)「ヒラギノ角ゴシックW4」にマッピングされていました。フォント名と実際のフォントの対応を調べるには以下のようなコードが使えます。

from matplotlib import font_manager

font_name = 'Hiragino sans'
font_prop = font_manager.FontProperties(family=font_name)
font_file = font_manager.findfont(font_prop)
print(f'{font_name} -> {font_file}')

フォント名とフォントファイルのマッピングを調べる

 ここでインポートしているmatplotlib.font_managerモジュールはフォントの検索、管理、使用についての機能やクラスがまとめられています。例えば、フォントの属性(フォントファミリー、スタイル、異体、フォントの伸縮、ウェイト、サイズ)などの情報を格納したり、操作したりするためのクラスであるFontPropertiesクラスや、FontPropertiesオブジェクトが表すフォントに最も近いフォントファイルのファイルパスを検索するfindfont関数などがあります。何より、TrueTypeフォントやAdobeのAFMフォントの一覧を管理するFontManagerクラスがあります。

 上のコードではそれらのうちのFontPropertiesクラスのインスタンスを生成していますが、そのときには上で述べた「Hiragino sans」というフォント名(フォントファミリー名)を与えています。そして、生成したFontPropertiesオブジェクトが表すフォント属性に最も近いフォントファイルのパスをfindfont関数で検索し、その結果をprint関数で出力しています。

 macOS上でこれを実行した結果を以下に示します(Windows上で実行すると、多くの場合はフォントが見つからずに「DejaVu sans」にフォールバックされます)。

「Hiragino sans」は「ヒラギノ角ゴシックW4」にマッピングされている 「Hiragino sans」は「ヒラギノ角ゴシックW4」にマッピングされている
W4はフォントのウェイト(太さ)を表し、W4は真ん中くらいの太さを意味する。

 font_managerモジュールについてはこの後でもちょっと取り上げます。

 なお、ここではpyplot.rcParams['font.sans-serif']の値を変更していましたが、以下のようにpyplot.rcParams['font.family']の値を直接書き換えてしまっても構いません。

plt.rcParams['font.family'] = ['Meiryo']

pyplot.rcParams['font.family']を直接変更する

 これは実は以下のコードと同じことをします。

import matplotlib

matplotlib.rc('font', family='Meiryo')

同じことをmatplotlib.rc関数で行う

fontlist.jsonファイル

 ところで、今見たフォント名はどうやって調べるんだ? と思うかもしれません(フォント名が分からなければ指定のしようがありませんから)。Matplotlibで使用できるフォントの一覧はmatplotlib.get_cachedir関数で取得できるディレクトリにfontlist-<バージョン>.jsonファイルとして記述されています(以下では簡単に「fontlist.json」と書くことにします)。

import matplotlib

matplotlib.get_cachedir()

fontlist.jsonファイルがあるディレクトリを調べる

 Windowsでこのコードを実行した結果を以下に示します。

実行結果 実行結果

 ここで得られたのは「'C:\\Users\\syngs\\.matplotlib'」というディレクトリです(これは「%USERPROFILE%\.matplotlib」ディレクトリに相当します)。以下はエクスプローラーでこのディレクトリを開いて、そこにあるfontlist-v390.jsonファイルをメモ帳に読み込んだところです(なぜかMatplotlib 3.10のfontlist.jsonファイルはできていなかったので別のバージョンのものを使用しています)。

fontlist.jsonファイルをメモ帳に読み込んだところ fontlist.jsonファイルをメモ帳に読み込んだところ

 上の画像では「meiryo」という文字列を検索しています。検索で見つかった部分にある"fname"要素がフォントファイルのパスを示し、"name"要素が先ほどのpyplot.rcParams['font.family']やpyplot.rcParams['font.sans-serif']に与えるフォント名です。

 自分で何かのフォントを使ってグラフにテキストを表示したいときには、このfontlist.jsonファイルを調べるとよいでしょう。

 あるいはプログラムとして、次のようにして日本語のフォントの名前を一覧することも可能です。ここでは先ほど紹介したfont_managerモジュールが公開しているFontManagerクラスのシングルトンインスタンスであるfont_manager.fontManagerを使います。

from matplotlib import font_manager

available_fonts = [f.name for f in font_manager.fontManager.ttflist]
jfont_list = ['Hiragino', 'Meiryo', 'Gothic', 'Mincho']

result = []
for font in available_fonts:
    for jfont in jfont_list:
        if jfont in font:
            result.append(font)
            break

print(result)

プログラム的に日本語フォントの名前を調べる

 font_manager.fontManagerオブジェクトにはttflist属性があり、ここには使用可能なフォントが列挙されています。それを反復して、フォント名を取り出したのがavailable_fontsです。また、jfont_listには日本語フォントに使われていそうな語を挙げています(日本語フォント以外でも使われている語も含まれている点には注意)。

 そして、両者を反復しながら、jfont_listの各要素が利用可能なフォントの名前に含まれていれば、まあ日本語フォントではなかろうかと判断して、そのフォント名をresult(日本語フォントの名前を格納するリスト)に追加しています。例えば、available_fontsの要素として反復されたのが'Hiragino sans'で、jfont_listの要素として反復されたのが'Hiragino'であれば、「'Hiragino' in 'Hiragino sans'」がTrueになるので、resultにこれを追加するといった具合です。

 また、font_managerモジュールにはfindSystemFonts関数もあります。これはシステムにインストールされているフォントを検索してくれます。これを使って同様なことも行えるかもしれません。

 ただし、既に述べたように「Gothic」は日本語フォントでも他の言語のフォントでも使われているので、実際には日本語フォントだけに限定できていないはずです。逆にjfont_listに列挙していない語だけで構成された日本語フォント名はこのチェックから抜け落ちることになることにもなります。実際に自分で同様なコードを実行する場合には気を付けてください(jfont_listを自分の必要に応じて調整しましょう)。

フォントファイルのパスを使ってフォントを指定する

 先ほど紹介したfontlist.jsonファイルにはフォントファイルのパスが記述されていました。このようなパスを与えて、グラフに記載するテキストのフォントを指定することも可能です。

 これには先ほども見たfont_managerモジュールのFontPropertiesクラスを使います。といっても、このクラスのインスタンスを生成する際にフォントファイルのパスを与えるだけです。後は、グラフのタイトルやラベルの描画時にそのオブジェクトをフォント情報として指定します。

 例えば、以下はWindowsとmacOSで異なるファイルパスを与えて、フォントを指定する例です。

import sys
from matplotlib import font_manager

if sys.platform == 'darwin':
    font_path = '/System/Library/Fonts/ヒラギノ角ゴシック W4.ttc'
elif sys.platform == 'win32':
    font_path = r'C:\Windows\Fonts\meiryo.ttc'

font_prop = font_manager.FontProperties(fname=font_path)
plt.plot([1, 2, 3], [1, 4, 9])
plt.title('グラフのタイトル', fontproperties=font_prop)
plt.xlabel('X軸', fontproperties=font_prop)
plt.ylabel('Y軸', fontproperties=font_prop)
plt.text(2, 5, 'グラフに日本語でテキストを追加(意味はない)', fontproperties=font_prop)
plt.legend(['データ1'], prop=font_prop)
plt.show()

フォントファイルのパスを使って日本語をグラフに表示する例

 ここではsysモジュールのplatform属性の値を基にmacOSでは「ヒラギノ角ゴシック W4」フォントを、Windowsでは「メイリオ」フォントを使うようにフォントファイルのパスを指定しています。そして、それらを基にFontPropertiesオブジェクトを作成します。

 作成したオブジェクトはpyplot.title関数やpyplot.xlabel関数などの呼び出し時にfontpropertiesパラメーターまたはpropパラメーターの値として渡します(pyplot.legend関数ではpropパラメーターになっている点に注意)。これにより、次のようなグラフが描画されます(グラフを描画するコードは、fontpropertiesパラメーターの指定を除けば、最初に定義したplot関数と同じです)。

フォントファイルのパスを使って、日本語を指定し、グラフを描画したところ(Windows) フォントファイルのパスを使って、日本語を指定し、グラフを描画したところ(Windows)

 フォントファイルのパスを直接指定したい場合には、このような方法を採ることになるでしょう。ですが、フォント名を推測できるのであれば、FontPropertiesオブジェクトの生成時にフォント名を与えてしまうのが簡単そうな気が筆者にはしました。

 また、常に日本語を使ったグラフ描画を行いたければ、.matplotlibrcファイルに設定を記述しておくことも可能です(これについては説明を省略します)。

japanize-matplotlibによる日本語を使ったグラフの描画

 ここまではpyplot.rcParams属性を使って日本語フォントを指定する、font_managerモジュールのFontPropertiesクラスを使って日本語フォントを指定する、という2つのやり方を見てきました。

 これらの方法は他に何も必要とせずに、グラフ内に日本語を含められるのでカンタンといえばカンタンです。が、多少のコードは必要になります。

 これをほんの1行のimport文だけで済ませられるモジュールがあります。それが「japanize-matplotlib」です。Pythonに標準で付属するわけではないので、前もってpipなどでインストールしておく必要がある点には注意してください(例:「pip3 install japanize-matplotlib」「py -3.13 -m pip install japanize-matplotlib」)。

 また、Python 3.12以降ではjapanize-matplotlibが内部的に使用しているdistutilsモジュールが標準で添付されなくなり、distutilsモジュール自体もsetuptoolsモジュールに統合されました。そのため、Python 3.12以降では「pip3 install setuptools」「py -3.13 -m pip install setuptools」などのコマンドでsetuptoolsモジュールをインストールしておく必要もあります。

 インストールができたら、後はmatplotlibをインポートした後に、japanize_matplotlibをインポートして、普通にグラフを描画するだけです(モジュール名にハイフンは使えないので、「japanize_matplotlib」と2つの単語をアンダーバーでつないでいる点に注意)。

import matplotlib.pyplot as plt
import japanize_matplotlib

def plot():
    plt.plot([1, 2, 3], [1, 4, 9])
    plt.title('グラフのタイトル')
    plt.xlabel('X軸')
    plt.ylabel('Y軸')
    plt.text(2, 5, '日本語のテキスト')
    plt.show()

plot()

japanize_matplotlibモジュールをインポートすればそれで全てよし!

 実行結果を以下に示します。

1行のimport文だけで日本語表示が可能になった 1行のimport文だけで日本語表示が可能になった

 これまでにダラダラと、日本語を表示するためにやってきたことはなんなんだったんだと思うくらいにカンタンに日本語が表示できました。とはいえ、ここまでに紹介してきたことが無駄かというとそういうわけでもありません。japanize-matplotlibは内部で次のようなコードを実行しています。

matplotlib.rc('font', family=FONT_NAME)

japanize-matplotlibではmatplotlib.rc関数でフォントファミリーを設定している

 この記事で既に紹介したmatplotlib.rc関数が使われていることが分かります。つまり、これまでに見てきたようなことを自動で行ってくれるのがjapanize-matplotlibモジュールというわけです。遠回りをして、最後に一番簡単な方法にたどり着きましたが、そこまでの内容を見てきたからこそ、なぜ簡単になっているのかが理解できるのが今回のポイントです。


 取りあえず、pyplot編はこの辺で終わることにします。本当はこの記事でseabornとの連携についても触れようと思っていたのですが、これについては次の「オブジェクト指向インタフェース編」の中で取り上げることにしましょう。

「Pythonデータ処理入門」のインデックス

Pythonデータ処理入門

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。