データを集めて集計するところまではできたのに、それを人に見せる段階で手が止まったことはありませんか。
数字がずらりと並んだ表を渡されても、受け取った側はどこを見ればいいのか迷ってしまいます。
そこで登場するのがmatplotlibです。Pythonでグラフを描くとき、いちばん最初に名前の挙がるライブラリです。
ただ、入門記事によって書き方がバラバラで、混乱した経験のある方も多いはずです。私も最初はそうでした。
この記事では、matplotlibが何をする道具なのかを、手元で動かせるコードだけで順番に確かめていきます。
matplotlibは、数字を絵に変えるライブラリ¶
まずは立ち位置の確認から始めましょう。matplotlibは、Pythonで扱っている数値をグラフの形に変えて出力するためのライブラリです。
折れ線グラフ、棒グラフ、散布図、ヒストグラム。研究論文に載るような図から、日報に貼る簡単なグラフまで、ひととおり描けます。
歴史はそれなりに長く、最初のリリースは2003年です。作者のJohn D. Hunterさんが、てんかん患者の脳波データを見るために作りはじめたのが出発点でした。
つまり、見た目を飾るためではなく、データを読み解くために生まれた道具ということです。この出自は、使っているうちに何となく伝わってきます。
現在はNumFOCUSという非営利団体が支援するプロジェクトとして開発が続いています。2026年8月時点の最新版は3.11.1で、Python 3.11以降が必要です。
データ分析まわりの土台になっているNumPyについては、こちらで解説しています。【関連記事】PythonのNumPyとは?配列計算がリストより速くなる仕組みを初心者向けに解説
インストールして、最初の1枚を描いてみる¶
matplotlibは標準ライブラリではないので、自分で追加します。pipで入ります。
作業用の仮想環境を用意してから、次のコマンドを実行してください。
pip install matplotlib
入ったら、さっそく1枚描いてみましょう。月ごとの売上を折れ線にする例です。
import matplotlib.pyplot as plt
months = [4, 5, 6, 7, 8]
sales = [120, 145, 138, 190, 205]
plt.plot(months, sales)
plt.show()
たった数行で、ウィンドウが開いて折れ線が表示されたはずです。ここまでは驚くほど簡単です。
読み込みのときの as plt は、ほぼ全世界共通の慣例です。他人のコードを読むときも同じ形で出てくるので、そのまま覚えてしまって構いません。
仮想環境の作り方があやしい方は、先にこちらを読んでおくと安心です。【関連記事】Pythonの仮想環境(venv)って何のためにある?プロジェクトごとに混ぜない管理法
FigureとAxesの2つがわかれば、もう迷わない¶
さて、ここからが本題です。matplotlibの入門でつまずく原因は、ほぼひとつに集約されます。
書き方が2種類あって、記事によってどちらかが使われているからです。その違いを理解する鍵が、FigureとAxesという言葉になります。
公式ドキュメントの説明では、matplotlibはFigureの上にデータを描き、Figureは1つ以上のAxesを含むことができるとされています。
言葉にすると難しく聞こえますが、中身は単純です。Figureが画用紙で、Axesがその上に置かれたグラフ1つぶんの領域。 そう思ってください。
画用紙は1枚でも、その上にグラフを2つ並べることができます。だから両者は別の名前を持っているわけです。
なお日本語で軸と訳されることが多いAxesですが、指しているのは軸そのものではなくグラフの領域全体です。ここは最初に引っかかりやすいところです。
plt.plot と ax.plot、どちらで書くべきか¶
さきほどのコードでは plt.plot を呼びました。この書き方では、Figureも Axesも裏側で勝手に作られています。
一方、自分で明示的に作ってから描く書き方もあります。同じグラフを、そちらのやり方で書き直してみましょう。
import matplotlib.pyplot as plt
months = [4, 5, 6, 7, 8]
sales = [120, 145, 138, 190, 205]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
plt.subplots() が画用紙とグラフ領域をセットで返し、それを fig と ax で受け取っています。あとは ax に対して指示を出すだけです。
行数は増えましたが、どこに何を描いているのかがはっきりしました。2つの書き方を並べて整理しておきます。
| pyplot方式(暗黙) | オブジェクト指向方式(明示) | |
|---|---|---|
| 書き出し | plt.plot(...) |
fig, ax = plt.subplots() |
| 描画の指示先 | 今開いているグラフ | 変数で受け取った ax |
| タイトルの付け方 | plt.title("...") |
ax.set_title("...") |
| 向いている場面 | 手早く1枚だけ確認する | 複数のグラフ、再利用するコード |
| 読みやすさ | 短いが対象があいまい | 長いが対象が明確 |
どちらが正しいという話ではありません。使い捨てなら前者、残すコードなら後者。 この選び分けで十分です。
私は10年ほどエンジニアとして開発に関わってきましたが、plt 方式で書いた確認用スクリプトをそのまま本番のレポート生成へ流用してしまい、グラフが2枚重なって出力される事故を起こしたことがあります。今は残すコードなら必ず fig, ax から書きはじめています。
グラフを2つ並べたいとき¶
明示的な書き方の利点が出るのが、複数のグラフを並べる場面です。plt.subplots に行数と列数を渡します。
fig, axes = plt.subplots(2, 1, figsize=(6, 6))
axes[0].plot(months, sales)
axes[0].set_title("Line")
axes[1].bar(months, sales)
axes[1].set_title("Bar")
fig.tight_layout()
plt.show()
axes に2つぶんのグラフ領域が入っているので、番号で指定して描き分けます。最後の tight_layout() は、タイトルや目盛りが重ならないように余白を調整してくれる呼び出しです。
折れ線以外のグラフも、流れは同じ¶
グラフの種類が変わっても、手順はまったく変わりません。ax に対して呼ぶメソッドを変えるだけです。
たとえば棒グラフなら bar、散布図なら scatter を使います。
fig, ax = plt.subplots()
ax.bar(["A店", "B店", "C店"], [30, 55, 42])
plt.show()
よく使うものを表にまとめておきます。困ったらここに戻ってきてください。
| 描きたいもの | 使うメソッド | 主な用途 |
|---|---|---|
| 折れ線グラフ | ax.plot(x, y) |
時間による変化を見る |
| 棒グラフ | ax.bar(x, y) |
項目どうしを比べる |
| 横向きの棒グラフ | ax.barh(y, x) |
項目名が長いとき |
| 散布図 | ax.scatter(x, y) |
2つの値の関係を見る |
| ヒストグラム | ax.hist(data) |
値のばらつきを見る |
| 円グラフ | ax.pie(data) |
構成比を見る |
種類を覚えるより、まず折れ線と棒だけを自在に扱えるようにするほうが実用的です。必要になった種類だけ、そのつど調べて足していけば十分。 これは他のライブラリでも同じです。
日本語が豆腐になる問題を先に片づける¶
さきほどの棒グラフを実行して、ラベルが四角い記号に化けた方がいるかもしれません。これは初心者がほぼ全員ぶつかる関門です。
原因は単純で、matplotlibが初期設定で使うフォントに日本語の文字が入っていないからです。表示できない文字が四角い枠になるため、豆腐と呼ばれます。
直し方は、日本語を含むフォントを指定してあげることです。設定は plt.rcParams という辞書のような入れ物を通して変更します。
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = "sans-serif"
plt.rcParams["font.sans-serif"] = [
"Meiryo", # Windows
"Hiragino Sans", # macOS
"Noto Sans CJK JP" # Linux
]
fig, ax = plt.subplots()
ax.bar(["A店", "B店", "C店"], [30, 55, 42])
ax.set_title("店舗別の売上")
plt.show()
候補をリストで並べておくと、上から順に探して見つかったものが使われます。OSの違う相手にコードを渡すときは、この書き方が安全です。
自分のパソコンにどのフォントが入っているかは環境によって違います。うまくいかないときは、まず候補のフォント名が実際に存在するかを確認してみてください。
描いたグラフを画像として保存する¶
画面に出すだけでなく、ファイルとして残したい場面も多いはずです。そのときは savefig を使います。
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.set_title("Monthly Sales")
fig.savefig("sales.png", dpi=200, bbox_inches="tight")
dpi は画像の細かさで、数字を上げるほど高解像度になります。bbox_inches="tight" を付けると、まわりの余白を切り詰めてくれます。
ひとつだけ順番の注意があります。保存は plt.show() より前に書く。 表示のあとだと、環境によっては中身が空の画像になってしまいます。
plt.show() を書いても何も出ないとき¶
スクリプトを実行したのにウィンドウが開かない、という相談はよく受けます。多くの場合、画面を持たない環境で実行しているのが原因です。
サーバー上やDockerコンテナの中には、そもそもウィンドウを表示する仕組みがありません。この場合は表示をあきらめて、savefig で画像に落とすのが正解です。
逆に、ブラウザだけで手軽に試したいならGoogle Colabが向いています。実行結果のすぐ下にグラフが表示されるので、環境まわりで悩む時間がなくなります。
【関連記事】Google Colabとは?PythonをPCにインストールせずに学べる環境を解説
pandasやNumPyと組み合わせると本領を発揮する¶
ここまではリストを直接渡してきましたが、実務ではpandasのデータフレームから描くことのほうが多くなります。
pandas側にも描画の機能があり、内部でmatplotlibを呼んでいます。ax を渡せば、これまでの書き方と自然につながります。
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
"month": [4, 5, 6, 7, 8],
"sales": [120, 145, 138, 190, 205],
})
fig, ax = plt.subplots()
df.plot(x="month", y="sales", ax=ax, marker="o")
ax.set_ylabel("Sales")
plt.show()
集計はpandasに任せて、見た目の調整だけmatplotlibで行う。 この分担が、いちばん素直な組み合わせ方です。
CSVを読み込んでそのままグラフにする流れまで作れると、日々の集計作業がかなり楽になります。【関連記事】pandas入門 データ処理をやってみよう
つまずきやすいところをまとめておく¶
最後に、初学者がぶつかりやすい点を整理しておきます。手元で困ったときの目次として使ってください。
| つまずき | 起きること | 対処 |
|---|---|---|
| 日本語が四角くなる | フォントに文字が入っていない | rcParams でフォントを指定する |
| ウィンドウが開かない | 画面のない環境で実行している | savefig で画像に保存する |
| 保存した画像が真っ白 | show() のあとに保存している |
savefig を先に書く |
| グラフが前の図に重なる | plt 方式で描き足している |
fig, ax = plt.subplots() から始める |
| ラベルが見切れる | 余白が足りていない | fig.tight_layout() を呼ぶ |
見た目を整えはじめると、色や線の太さなど調整できる項目がいくらでも出てきます。ただ、最初からそこに時間をかける必要はありません。
まずは数字が正しく形になっていること。 装飾は、伝えたい内容が固まってからで間に合います。
グラフが描けるようになると、自分の書いたコードの結果を目で確かめられるようになります。学習の手応えという意味でも、ここは通っておく価値のある場所です。
ここまでお読みいただきありがとうございました。