python グラフ作成を完全攻略!Matplotlibで基本〜応用まで図解

この記事ではPythonのMatplotlibでグラフを描く手順を、インストールから基本のplot、棒・散布図、ヒストグラム、複数図の並べ方、軸・ラベル・凡例・色などの装飾、保存方法、日本語表示まで具体例で解説。思い通りに可視化できない悩みを解決します。

目次

Pythonでグラフを描くメリットと全体像

ocean+view

Pythonグラフは、データの傾向や異常値、比較結果を「ひと目で伝わる形」に変換できるのが大きなメリットです。表や数値の羅列では見落としがちなパターンも、グラフにすることで意思決定に直結する気づきが得られます。また、Pythonはデータ加工から可視化までを同じコード内で一貫して行えるため、分析の再現性(同じ手順で何度でも同じ結果を作れる)や自動化との相性も良い点が特徴です。

全体像としては、まず「データの種類(時系列・カテゴリ・分布・相関など)」を整理し、次に「何を伝えたいか(推移、比較、ばらつき、関係性など)」を決めることで、適切なグラフの種類が自然に選べるようになります。つまり、Pythonでグラフを描く際は、見た目の好みよりも目的に沿った選択が重要です。

どんなデータをどんなグラフで可視化できるか

Pythonグラフで可視化できる対象は幅広く、代表的には「時間」「カテゴリ」「数値の分布」「2変数以上の関係」「2次元の値(面データ)」などです。ここでは、データのタイプ別に、相性のよいグラフを整理します。

まず、時系列データ(例:日次売上、気温、アクセス数の推移)には、変化の流れを追いやすい折れ線グラフが適しています。増減のタイミングや季節性、トレンドが把握しやすく、「いつから変化したか」を説明しやすいのが強みです。データ点が多いほど折れ線の価値が高まります。

次に、カテゴリ別の比較(例:商品カテゴリ別の売上、支店別の成約数、アンケート回答の内訳)には棒グラフが向きます。カテゴリ間の差を直感的に比較でき、ランキングや平均との差のような説明にも使いやすいです。カテゴリ数が多い場合は、読みやすさの観点で並び順の工夫が重要になります。

数値のばらつきや頻度を見たい場合(例:購入単価の分布、作業時間の分布、テスト点数の散らばり)にはヒストグラムが有効です。「どの値が多いか」「偏りがあるか」「外れが存在するか」を把握でき、平均だけでは説明できない特徴を捉えられます。分布の形(山が1つか複数か、裾が長いかなど)を読み取る用途に向きます。

2つの数値の関係性(例:広告費と売上、身長と体重、学習時間と点数)を確認したいときは散布図が定番です。点の集まり方から相関の有無、線形か非線形か、外れ値の存在などを判断できます。関係性の可視化は、仮説検証やモデル化の前段として特に重要です。

分布をグループ間で比較したい場合(例:部署別の残業時間、施策A/Bの効果、地域別の単価差)には箱ひげ図が適しています。中央値や四分位範囲、外れ値を同時に示せるため、「平均は同じでもばらつきが違う」といった差を説明しやすくなります。複数グループを並べても視認性が保たれやすい点もメリットです。

割合構成(例:売上構成比、アンケート比率、費用内訳)を見せたい場合は円グラフが使われることもありますが、比較対象が多いと判別しづらくなるため注意が必要です。比率の強調が目的で、カテゴリ数が少なく、差が明確なときに限って有効になりやすい可視化です。

さらに、2次元データ(例:座標ごとの温度分布、地図や画像に近い格子状データ、シミュレーション結果)には、メッシュ表示や等高線のような表現が適します。点の集合では伝えにくい「面としての濃淡」や「境界」を捉えられるため、空間的な偏りやピークの位置を把握しやすくなります。

まとめると、Pythonグラフは「推移なら折れ線」「比較なら棒」「分布ならヒストグラム/箱ひげ」「関係なら散布図」「構成比なら円(注意)」「面データならメッシュ/等高線」という整理が基本になります。まずは自分のデータがどのタイプに当たるかを見極めることが、迷わず可視化を進める近道です。

Matplotlibとは何か(他ライブラリとの位置づけ)

python+matplotlib+visualization

「python グラフ」といえば、まず名前が挙がるのがMatplotlibです。MatplotlibはPythonにおける可視化の“土台”として広く使われている定番ライブラリで、折れ線・棒・散布図などの基本的なグラフから、細かな見た目調整まで幅広く対応できます。多くの可視化ライブラリがMatplotlibをベースに設計されていることも多く、最初に押さえておくと他ツールへ発展しやすいのが特徴です。

位置づけとしては、「汎用で自由度が高いが、最初は記述がやや多くなりがち」というタイプです。その代わり、論文・レポート向けの静的な図をきっちり作り込む用途や、細部まで指定して再現性の高い画像を作る用途に強みがあります。

Matplotlibでできること・得意領域

Matplotlibの強みは、描けるグラフの種類が多いことと、見た目(スタイル)を細部まで制御できることです。分析の初期段階での素早い可視化から、提出物として体裁を整えた図の作成まで対応できます。

  • 基本グラフの網羅:折れ線、棒、散布図、ヒストグラム、箱ひげ図、円グラフなどの定番を一通りカバーできます。
  • 細かなカスタマイズ:タイトル、軸ラベル、凡例、目盛り、色、線種、フォント、余白などを細かく調整し、意図した「伝わる図」に仕上げられます。
  • 出力のしやすさ:PNGやSVG、PDFなど、用途に合わせた形式で書き出せるため、資料・Web・印刷物まで幅広く対応可能です。
  • 再現性の高い図づくり:コードで図の仕様を固定できるので、毎回同じルールでpython グラフを生成したいときに向きます(定期レポートや自動生成にも相性が良い)。

一方で、統計可視化を「いい感じ」に整えることや、インタラクティブに操作できるグラフを作ることは、専用ライブラリのほうが得意な場合があります。そのため、Matplotlibは“基礎体力”として押さえつつ、目的に応じて他ライブラリと使い分けるのが現実的です。

Seaborn・Plotly・Pandasプロットとの違いと使い分け

Matplotlib以外にも、Pythonにはグラフ作成の選択肢が複数あります。ここでは、よく比較されるSeaborn・Plotly・Pandasプロットを「何が違うか」「どう使い分けるか」の観点で整理します。

ライブラリ得意なこと向いている場面注意点
Matplotlib自由度が高い、静的な図の作り込み、出力形式が豊富論文・レポート品質の図、細部まで指定したいpython グラフ初学者には記述量が多く感じることがある
Seaborn統計可視化、見栄えの良いデフォルト、カテゴリ比較や分布の表現探索的データ分析(EDA)、箱ひげ図・バイオリン図・ヒートマップ等細かな最終調整はMatplotlib側の知識が必要になることが多い
Plotlyインタラクティブ(拡大・ホバー表示)、ダッシュボード適性Web共有、操作しながら確認したい分析、プレゼンで動くグラフ静的出力や環境によっては追加設定が必要な場合がある
PandasプロットDataFrameから手軽に描画(内部はMatplotlibベース)まず素早く可視化して当たりをつけたいとき凝った調整をするなら結局Matplotlibの理解が必要

使い分けの目安としては、次のように考えると選びやすくなります。

  • 「細部まで整えた静的な図を安定して作りたい」:Matplotlibが最有力です。
  • 「分布や相関など、統計的な見せ方を手早くきれいに」:Seabornが向きます(必要に応じてMatplotlibで仕上げ)。
  • 「触れるグラフで共有・説明したい(ホバーで値表示など)」:Plotlyが適しています。
  • 「とにかく一旦、DataFrameをそのまま描いて状況把握したい」:Pandasプロットが便利です。

また、現場では「Pandasでざっくり→Seabornで分析向けに整形→最終版はMatplotlibで微調整して出力」のように、組み合わせて使うことも珍しくありません。python グラフ作成の中心としてMatplotlibを理解しておくと、こうした使い分けがスムーズになります。

事前準備:インストールと実行環境の整え方

python+matplotlib+visualization

Pythonでグラフを描くには、まず「ライブラリのインストール」「コード内での読み込み」「日本語が文字化けしない設定」という3点を押さえるのが近道です。ここでは、定番ライブラリであるMatplotlibを使って、python グラフ作成をスムーズに始めるための事前準備を整理します。

Matplotlibのインストール手順

MatplotlibはPythonの代表的な可視化ライブラリで、折れ線・棒・散布図など多くのグラフ描画に対応します。インストール方法は利用環境(pip/conda)によって主に2通りです。

pipでインストールする場合

python -m pip install matplotlib

複数のPythonが入っている環境では、意図したPythonに対してpipが動いていないことがあります。その場合は上記のように python -m pip 形式にすると、実行しているPythonに紐づいたpipでインストールできます。

Anaconda(conda)でインストールする場合

conda install matplotlib

インストール確認

入ったかどうかは、Python上でバージョン表示ができれば確認できます。

python -c "import matplotlib; print(matplotlib.__version__)"

注意:インストールできても、実行環境(例:Jupyter/VS Code/ターミナル)で参照しているPythonが別だと、importで失敗します。 その場合は、現在使っている環境のPython/カーネルがどれかを見直し、同じ環境にMatplotlibを入れてください。

必要なモジュールの読み込み(pyplot等)

Matplotlibは「どの機能を使うか」で読み込み方が変わりますが、python グラフ作成で最もよく使うのは matplotlib.pyplot です。一般に plt という別名で読み込みます。

import matplotlib.pyplot as plt

加えて、数値データを作ったり配列を扱ったりするためにNumPyを一緒に使うケースも多いです(グラフ作成時の前処理が楽になります)。

import numpy as np
import matplotlib.pyplot as plt

また、「1枚の図に複数のグラフを描く」「細かな体裁を整える」場面では、オブジェクト指向の書き方と相性が良いので、次のように subplots を使う準備もしておくと便利です。

fig, ax = plt.subplots()

まずは import matplotlib.pyplot as plt を確実に書ける状態にしておくと、以降の手順がスムーズに進みます。

日本語表示のための設定(フォント・日本語化)

python グラフでタイトルや凡例、軸ラベルを日本語にすると、環境によっては文字化け(□や?になる)することがあります。これはMatplotlibが既定で日本語フォントを見つけられない/選ばないことが原因です。対策は大きく「フォントを指定する」か「日本語対応を簡単にする仕組みを使う」かの2つです。

方法1:Matplotlibのフォントを明示的に指定する

環境にインストールされている日本語フォント名を指定します。代表例としては、Windowsなら「MS Gothic」「Meiryo」、macOSなら「Hiragino Sans」などが候補になります(利用可能な名称は環境で異なります)。

import matplotlib.pyplot as plt

plt.rcParams["font.family"] = "MS Gothic"   # 例:Windows
plt.rcParams["axes.unicode_minus"] = False  # マイナス記号が文字化けする場合の対策

axes.unicode_minus は、負の値を含む軸目盛りで「−」が四角になる問題の回避に有効です。

方法2:日本語化用の補助パッケージを使う

環境差を吸収しやすい方法として、日本語フォント設定を補助するパッケージを導入する手もあります。導入後は読み込むだけで日本語表示が改善することがあります。

python -m pip install japanize-matplotlib
import matplotlib.pyplot as plt
import japanize_matplotlib

どちらを選ぶべきか

  • 特定の実行環境(社内PCなど)で運用する:方法1(フォント固定)が安定しやすい
  • 複数環境・学習用途で手早く進めたい:方法2(補助パッケージ)が手軽

日本語設定ができていると、グラフの可読性が上がり、レポートや資料にそのまま使える品質になります。まずは「自分の実行環境で日本語が崩れない」状態を作ることが重要です。

Matplotlibの基本操作(最小コードで描く)

python+matplotlib+visualization

プロット作成の基本フロー(Figure/Axesの考え方)

Pythonでグラフを描くとき、Matplotlibでは「どこに(キャンバス)」「何を(座標軸)」「どう描く(線・点・棒など)」を分けて考えると理解が一気に楽になります。最小コードでも動きますが、少しだけ構造を押さえると後の拡張(複数グラフ、見た目調整、保存)までスムーズです。

Matplotlibの基本要素は次の2つです。

  • Figure:図全体(キャンバス)。1枚の画像・ウィンドウのイメージ
  • Axes:実際にデータを描く領域(座標軸を持つ「描画面」)。Figureの中に1つ以上置ける

このFigure/Axesを明示して作るスタイルが、いわゆる「オブジェクト指向(OO)スタイル」です。可視化が複雑になっても破綻しにくく、Pythonでグラフを作るならまずこの形を最小セットとして覚えるのが近道です。

import matplotlib.pyplot as plt

# 1) Figure と Axes を作る
fig, ax = plt.subplots()

# 2) Axes に対して描画する(例:折れ線)
x = [0, 1, 2, 3]
y = [0, 1, 4, 9]
ax.plot(x, y)

# 3) 必要なら体裁を少し整える(最低限)
ax.set_title("Sample")
ax.set_xlabel("x")
ax.set_ylabel("y")

ポイントは「描画命令はaxに対して行う」ことです。ax.plot()のようにAxesメソッドを使うと、どの領域に描いたのかが明確になります。これが「python グラフ」を安定して作るための基本フローです。

グラフを画面に表示する方法

作成したグラフを画面に表示する基本はplt.show()です。スクリプト実行(.py)では、最後にこれを書いて表示を確定させるのが定石です。

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4])

plt.show()

表示の挙動は実行環境で少し変わります。

  • ローカルのPython実行(ターミナル等):plt.show()でウィンドウが開く
  • ノートブック環境:セル実行で自動表示されることもあるが、明示的にplt.show()を書くと意図が明確

また、複数の図を作る場合でも、基本は「作る→必要なら調整→最後にshow」でOKです。表示を先に呼ぶと、その後の追加描画が反映されないことがあるため、表示は最後にまとめるのが安全です。

画像として保存・書き出す方法

作成したpython グラフをレポートや資料に使うなら、画像保存は必須です。Matplotlibではsavefigで簡単に書き出せます。おすすめは「Figureに対して保存する」方法で、どの図を保存するのかが明確になります。

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4])

# PNGで保存(ファイル名だけでOK)
fig.savefig("graph.png")

保存時に押さえたい実務的な設定は次の通りです。

  • 解像度dpiを上げると高精細(印刷・資料向け)
  • 余白の自動調整bbox_inches="tight"で切れやすいラベルを収めやすい
  • 形式:拡張子で自動判定(例:.png、.jpg、.pdf、.svg)
# 例:余白を詰めて高解像度で保存
fig.savefig("graph.png", dpi=300, bbox_inches="tight")

なお、保存はplt.show()の前に実行しておくと、環境によってはより確実です(表示後に図が閉じられる挙動があるため)。最小コードで始めつつ、保存までをセットにすると「作って終わり」ではなく再利用できるグラフ運用に繋がります。

折れ線グラフの描き方(plotの基本)

python+matplotlib+plot

Pythonでグラフを描く際、最も基本となるのが折れ線グラフです。Matplotlibのplotを使えば、時系列の推移や数値の増減を直感的に可視化できます。このセクションでは「単系列」「複数系列」「文字列(カテゴリ)を横軸にする」3パターンに絞って、Python グラフ作成の基礎を押さえます。

単系列の折れ線を描く

まずは1本の線(単系列)を描くところから始めます。x(横軸)とy(縦軸)を用意し、plt.plot(x, y)で折れ線グラフを作れます。横軸を省略してplt.plot(y)と書くこともできますが、意図した軸になっているか確認しやすいように、基本はxも指定するのがおすすめです。

import matplotlib.pyplot as plt

# 例:日ごとの売上推移(単系列)
x = [1, 2, 3, 4, 5]
y = [10, 12, 9, 14, 16]

plt.plot(x, y)
plt.show()

単系列の折れ線グラフでは、次のようなポイントを押さえると読みやすくなります。

  • xyの長さ(要素数)を揃える
  • 欠損や異常値がある場合は、意図せず線が飛んだり極端に伸びたりしないか確認する
  • データが離散的ならマーカーを付けるなど、視認性を意識する

複数系列の折れ線を重ねて描く

比較したい系列が複数ある場合は、plotを複数回呼び出して同じ座標上に重ねます。Python グラフの中でも、複数系列の折れ線は「施策Aと施策Bの推移」「製品ごとの温度変化」など比較用途で頻出です。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y_a = [10, 12, 9, 14, 16]
y_b = [8, 11, 13, 12, 15]

plt.plot(x, y_a, label="A")
plt.plot(x, y_b, label="B")

plt.legend()
plt.show()

複数系列では、線が増えるほど判別が難しくなります。最低限、凡例(labellegend)は付けるとよいでしょう。また、次の点を意識すると比較の精度が上がります。

  • 系列ごとにlabelを付け、凡例で意味を明確化する
  • 系列間でxの定義(期間・粒度・単位)を揃える
  • 系列が多すぎる場合は、比較したいものに絞る(線が重なり読めなくなるのを防ぐ)

文字列(カテゴリ)を横軸に使う方法

横軸に数値ではなく、月名・曜日・商品カテゴリなどの文字列(カテゴリ)を使いたい場面もあります。Matplotlibのplotは、カテゴリのリストをxとして渡すことで、カテゴリ軸として扱えます。これにより「カテゴリごとの変化」を折れ線として表現できます。

import matplotlib.pyplot as plt

# 例:月別の値(カテゴリを横軸に)
x = ["Jan", "Feb", "Mar", "Apr", "May"]
y = [100, 120, 110, 140, 160]

plt.plot(x, y, marker="o")
plt.show()

カテゴリ軸は便利ですが、次のような注意点があります。

  • カテゴリの順序は、リストの並び順がそのまま反映される(意図した並びになっているか確認)
  • カテゴリ数が多いとラベルが詰まりやすい(必要ならカテゴリを間引く、短縮名にするなど工夫する)
  • 「連続量としての時間」を表したい場合は、カテゴリ文字列よりも数値や日付にしたほうが解釈が自然なことがある

棒グラフの作り方

python+matplotlib+visualization

Pythonでグラフを作る場面の中でも、棒グラフは「カテゴリごとの量を比較する」用途で特に出番が多い可視化です。例えば、部署別の売上、月別の件数、商品カテゴリ別の利用者数など、離散的な項目を並べて差を一目で把握できます。ここでは、Matplotlibを使った棒グラフ(縦棒・横棒)の基本と、見栄えを整えるための代表的な調整方法をまとめます。

縦棒・横棒の基本

Matplotlibで棒グラフを描く基本は、縦棒ならbar()、横棒ならbarh()を使うことです。どちらも「軸(位置)」と「値」を渡すだけで描画でき、Python グラフの入門としても理解しやすい形式です。

まずは縦棒グラフの最小構成です。カテゴリ名を横軸、数値を縦軸にして比較します。

import matplotlib.pyplot as plt

labels = ["A", "B", "C", "D"]
values = [12, 7, 15, 9]

plt.figure(figsize=(6, 4))
plt.bar(labels, values)
plt.show()

一方、項目名が長くて横軸に置くと読みにくい場合や、ランキングのように上から下へ並べたい場合は横棒が便利です。横棒はカテゴリを縦軸に置くため、ラベルが読みやすくなる傾向があります。

import matplotlib.pyplot as plt

labels = ["カテゴリA", "カテゴリB", "カテゴリC"]
values = [120, 80, 150]

plt.figure(figsize=(6, 4))
plt.barh(labels, values)
plt.show()

縦棒(bar)と横棒(barh)は、向きが違うだけで考え方は同じです。どちらを選ぶかは「ラベルの読みやすさ」「並べたい順序」「比較の目的」に合わせて決めるのがポイントです。

棒グラフの見栄え調整(幅・色・ラベル)

棒グラフは描けたとしても、資料やレポートに使うなら「見やすさ」を整えることが重要です。Python グラフでは、棒の幅・色・ラベル(値の注釈)を調整するだけでも読み取りやすさが大きく変わります。

棒の幅はwidth(縦棒)やheight(横棒)で調整できます。カテゴリ数が少ないのに棒が細すぎる、逆に多すぎて棒が詰まりすぎる、といった違和感を解消できます。

import matplotlib.pyplot as plt

labels = ["A", "B", "C", "D"]
values = [12, 7, 15, 9]

plt.figure(figsize=(6, 4))
plt.bar(labels, values, width=0.6)  # 棒を少し太めに
plt.show()

色はcolorで指定します。単色で統一すると落ち着いた印象になり、強調したい棒だけ色を変えると視線誘導ができます。

import matplotlib.pyplot as plt

labels = ["A", "B", "C", "D"]
values = [12, 7, 15, 9]

colors = ["#4C72B0", "#4C72B0", "#DD8452", "#4C72B0"]  # Cだけ強調

plt.figure(figsize=(6, 4))
plt.bar(labels, values, color=colors)
plt.show()

さらに、棒の上(または横)に数値ラベルを表示すると、グラフを見ただけで正確な値が読み取れるようになります。Matplotlibでは、描画後に各バーを走査してテキストを配置する方法が実務でよく使われます。

縦棒グラフに値ラベルを付ける例です。

import matplotlib.pyplot as plt

labels = ["A", "B", "C", "D"]
values = [12, 7, 15, 9]

plt.figure(figsize=(6, 4))
bars = plt.bar(labels, values, color="#4C72B0", width=0.6)

for bar in bars:
    x = bar.get_x() + bar.get_width() / 2
    y = bar.get_height()
    plt.text(x, y, f"{y}", ha="center", va="bottom")

plt.show()

横棒グラフの場合は、右側に値を出すと自然に読めます。

import matplotlib.pyplot as plt

labels = ["カテゴリA", "カテゴリB", "カテゴリC"]
values = [120, 80, 150]

plt.figure(figsize=(6, 4))
bars = plt.barh(labels, values, color="#4C72B0", height=0.6)

for bar in bars:
    x = bar.get_width()
    y = bar.get_y() + bar.get_height() / 2
    plt.text(x, y, f"{x}", ha="left", va="center")

plt.show()

幅・色・ラベルの3点を押さえるだけで、棒グラフは「ただ描いた図」から「比較しやすいPython グラフ」へと一段引き上がります。用途に応じて、強調したい要素だけ色を変える、値ラベルで読み取りを補助する、といった調整を加えていくのが効果的です。

散布図の作り方

python+matplotlib+visualization

散布図の基本(点の描画)

散布図は、2つの数値データの関係(相関の傾向、ばらつき、外れ値など)を直感的に把握できるグラフです。Pythonでグラフを描く際は、Matplotlibのscatterを使うことで、X軸・Y軸に対応する点を簡単にプロットできます。

最小構成では「Xの配列」と「Yの配列」を用意し、plt.scatter(x, y)で点を描画します。点の数が多くても、コードはほぼ変わりません。

import matplotlib.pyplot as plt

# 例:XとYに対応するデータ
x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 4, 6]

plt.scatter(x, y)
plt.show()

この基本形だけでも、以下のような確認ができます。

  • 右上がり/右下がりなどの相関の雰囲気
  • 特定の範囲に点が集中しているか(密集)
  • 他と離れた外れ値が存在するか

なお、散布図では「XとYの要素数が同じ」ことが前提です。要素数がズレているとエラーや意図しない描画になるため、データ準備の段階で揃っているかを確認してから描画すると安定します。

マーカー・サイズ・色で情報を追加する

Pythonで散布図を描くメリットの一つは、点の見た目(マーカー形状・サイズ・色)に追加情報を載せられることです。これにより、単なる2変数の関係だけでなく「第三の変数」「カテゴリ差」「重要度」などを同時に表現できます。

よく使う指定は次の3つです。

  • marker:点の形(例:'o', 'x', 's'
  • s:点のサイズ(数値、配列も可)
  • c:点の色(固定色、配列、カラーマップ指定が可能)

まずは、形・サイズ・色を固定値で指定して「見やすい散布図」に整える例です。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 4, 6]

plt.scatter(
    x, y,
    marker='o',   # マーカー形状
    s=80,         # 点の大きさ
    c='tab:blue'  # 点の色
)
plt.show()

次に、サイズや色を配列で渡すと、点ごとに情報を変えられます。たとえばsに別の数値(重要度・人数・売上など)を割り当てれば、バブルチャートのように表現できます。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 4, 6]
size = [20, 50, 200, 80, 120]  # 点ごとのサイズ

plt.scatter(x, y, s=size, marker='o', c='tab:green')
plt.show()

色で「第三の変数」を表したい場合は、cに数値配列を渡し、cmap(カラーマップ)を指定します。これにより、値の大小が色の濃淡として表現され、散布図が一段と読み取りやすくなります。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 4, 6]
z = [10, 30, 90, 50, 70]  # 色で表したい値(第三の変数)

plt.scatter(x, y, c=z, cmap='viridis', s=100, marker='o')
plt.show()

このとき、色の意味を明確にするには「何の値で色が変わっているか」を意識して設計することが重要です。特にデータ分析用途では、サイズと色を同時に使うことで、Pythonの散布図だけで複数の観点(位置=2変数、色=3変数、サイズ=4変数)を一画面にまとめられます。

円グラフの作り方

python+matplotlib+visualization

Pythonでグラフを作る際、円グラフは「全体に対する内訳(構成比)」を直感的に伝えたいときに便利です。Matplotlibではpie()を使って円グラフを描けますが、読み手の誤解を招きやすい側面もあるため、作り方と同時に注意点(使いどころ)を押さえることが重要です。

円グラフの基本と注意点(使いどころ)

円グラフは「100%をいくつかの比率に分けたもの」を可視化するグラフです。たとえば、カテゴリ別の割合(売上構成、アンケート回答の比率、費目の内訳など)を示すのに向いています。反対に、値の大小比較や差分の強調には不向きなことが多いので、状況に応じて使い分ける必要があります。

まずは、Matplotlibでの基本形です。labelsにカテゴリ名、sizesに比率(または比率に比例する数値)を渡します。構成比を読みやすくするために、autopctでパーセンテージ表示を付けるのが定番です。

import matplotlib.pyplot as plt

labels = ["A", "B", "C", "D"]
sizes = [40, 25, 20, 15]

plt.figure(figsize=(6, 6))
plt.pie(
    sizes,
    labels=labels,
    autopct="%.1f%%",   # 小数1桁の割合表示
    startangle=90       # 開始角度を揃えて見やすく
)
plt.title("構成比の円グラフ")
plt.axis("equal")       # 円を真円にする(重要)
plt.show()

円グラフを「円」として歪みなく表示するには、plt.axis("equal")が実務上ほぼ必須です。これがないと表示領域の都合で楕円になり、比率の印象が変わってしまうことがあります。

次に、よく使われる見栄え調整として「特定の項目を強調する」方法があります。explodeで一部のスライスを外側にずらし、注目してほしいカテゴリを目立たせます。

import matplotlib.pyplot as plt

labels = ["主要", "次点", "その他"]
sizes = [55, 30, 15]
explode = (0.08, 0.0, 0.0)  # 先頭(主要)だけ少し外へ

plt.figure(figsize=(6, 6))
plt.pie(
    sizes,
    labels=labels,
    explode=explode,
    autopct="%.0f%%",
    startangle=90
)
plt.title("特定カテゴリを強調した円グラフ")
plt.axis("equal")
plt.show()

一方で、円グラフには明確な注意点があります。Pythonでグラフを作るときほど「描ける」ことと「伝わる」ことは別なので、使いどころを意識しましょう。

  • カテゴリ数が多い円グラフは避ける:スライスが細かくなり、ラベルも重なって読みにくくなります。目安として6〜7区分を超えると急に判読性が落ちます。

  • 近い割合同士の比較に弱い:25%と27%のような僅差は、角度・面積の知覚では判別しづらいです。順位比較が主目的なら別形式が望ましいケースが多いです。

  • 時系列や推移を表す用途には不向き:円グラフは「その時点の内訳」を示すのが得意で、変化の流れを追う用途には向きません。

  • 3D表現は原則避ける:奥行きで面積が歪み、比率を誤認しやすくなります(視覚的に派手でも正確性が下がります)。

円グラフが有効な典型例は、「全体の中で主要カテゴリがどれか」を一目で伝えたい場面です。たとえば、上位1〜3カテゴリが大半を占めるようなデータでは、スライスの大きさの差が明確になり、直感的な理解に繋がります。

最後に、円グラフの入力値(sizes)に関する基本も押さえておくと安心です。pie()は合計が100でなくても、与えた値の合計を基準に自動で割合に正規化して描画します。ただし、負の値が混ざるとエラーになりやすいため、構成比として妥当な(0以上の)データになっているかは事前に確認しましょう。

ヒストグラムの作り方

python+matplotlib+histogram

Pythonでグラフを作る際、データの「分布(ばらつき・偏り)」を直感的に把握したいならヒストグラムが有効です。ヒストグラムは、数値データを一定幅の区間(ビン)に区切り、各区間に入る件数(または割合)を棒で表します。たとえば売上、滞在時間、身長、センサー値などの連続値に対して、中心がどこにあるか、裾が長いか、外れ値がありそうかを一目で確認できます。

Matplotlibでは plt.hist()(または ax.hist())で描画します。まずは最小限の例を押さえておくと、以降の調整がスムーズです。

import numpy as np
import matplotlib.pyplot as plt

# 例:正規分布っぽいデータ
x = np.random.normal(loc=50, scale=10, size=1000)

plt.hist(x)
plt.show()

分布を可視化する基本設定(ビンの調整など)

ヒストグラムの読みやすさは「ビンの切り方」で大きく変わります。ビン幅が粗すぎると特徴が潰れ、細かすぎるとノイズが強調されます。ここでは、Pythonでグラフ(ヒストグラム)を調整するうえで必須の設定をまとめます。

bins:ビン数(または境界)を指定する

bins は最重要パラメータです。数値で渡すと「ビン数」、配列で渡すと「ビン境界」を明示できます。

  • ビン数で指定:ざっくり形を確認したいときに便利
  • 境界で指定:ビジネス上の区切り(例:0〜10、10〜20…)に合わせたいときに便利
plt.hist(x, bins=30)  # ビン数を30に
# 境界を明示(例:0〜100を5刻み)
edges = np.arange(0, 101, 5)
plt.hist(x, bins=edges)

density:件数ではなく「確率密度」で比較する

サンプル数が異なるデータ同士を比較する場合、単純な件数だと棒の高さがサンプル数に引っ張られます。density=True にすると、面積が1になるように正規化され、分布の形状比較がしやすくなります。

plt.hist(x, bins=30, density=True)

range:表示範囲を固定して外れ値の影響を抑える

外れ値があると自動スケールで横軸が広がり、中心部分が潰れて見えることがあります。range=(min, max) で可視化したい範囲を固定すると、分布の主要部分に焦点を当てられます。

plt.hist(x, bins=30, range=(0, 100))

histtype / rwidth:見た目を整えて読みやすくする

棒が密集すると視認性が下がるため、棒の幅や表現形式を調整します。

  • rwidth:棒の幅(隙間)を調整(例:0.9で少し隙間)
  • histtype"bar"(棒)、"step"(輪郭線)など
plt.hist(x, bins=30, rwidth=0.9, histtype="bar")
plt.hist(x, bins=30, histtype="step", linewidth=2)

alpha / color / edgecolor:重なりや輪郭を調整する

棒が重なったり背景と同化したりすると読みづらくなります。alpha(透明度)や edgecolor(枠線)を付けると改善しやすいです。

plt.hist(x, bins=30, color="tab:blue", edgecolor="white", alpha=0.85)

複数データの比較:同じbinsで揃える

2つ以上の分布を比較する場合は、同一のビン境界で揃えるのが鉄則です。ビンがズレると「見かけの差」が生まれ、解釈を誤りやすくなります。bins を共有し、必要に応じて alpha を下げて重なりを見えるようにします。

x1 = np.random.normal(50, 10, 1000)
x2 = np.random.normal(55, 12, 1000)

edges = np.arange(0, 101, 5)  # 共通のビン境界
plt.hist(x1, bins=edges, alpha=0.6, label="A")
plt.hist(x2, bins=edges, alpha=0.6, label="B")
plt.show()

自動ビン推定を使う:FD(Freedman–Diaconis)など

ビン数を手で決めにくいときは、自動推定を使うのも実務的です。Matplotlibの bins は文字列指定も可能で、代表例として "fd"(Freedman–Diaconis)などがあります。データ量や散らばりに応じたビン幅を提案してくれるため、初期探索に向きます。

plt.hist(x, bins="fd")

解釈の注意:ビン設定で印象が変わる

ヒストグラムはビンの切り方次第で形状の印象が変わります。特に「山がいくつあるか(単峰性/多峰性)」や「裾の長さ(歪度)」は、ビン幅の影響を受けやすいポイントです。Pythonでグラフを作る際は、bins を複数パターンで試し、同じ傾向が見えるか確認すると信頼性が上がります。

箱ひげ図で分布を比較する

python+matplotlib+visualization

箱ひげ図(ボックスプロット)は、データの「ばらつき」「中心」「外れ値」をひと目で把握できる代表的な可視化です。python グラフの中でも、複数グループの分布を並べて比較したいときに特に有効で、平均値だけでは見落としがちな偏りや外れ値の存在を直感的に捉えられます。

箱ひげ図の基本と読み取り方

箱ひげ図は、主に「中央値」「四分位範囲(IQR)」「ひげ」「外れ値」で構成されます。まずは各パーツが何を意味するのかを押さえると、見た目の情報から正しく判断できるようになります。

  • 箱(ボックス):第1四分位(Q1)〜第3四分位(Q3)を表します。箱の高さ(縦方向の場合)が大きいほど、中央50%のデータのばらつきが大きいことを示します。
  • 中央値(メディアン):箱の中の線が中央値(Q2)です。グループ間でこの線の位置を比べることで、典型値の違いを比較できます。
  • ひげ(whisker):一般的には「Q1 – 1.5×IQR」〜「Q3 + 1.5×IQR」の範囲内にある最小値・最大値まで伸びます(IQR=Q3-Q1)。
  • 外れ値(outlier):ひげの範囲を超えた点が個別の点として表示されることが多く、極端に大きい/小さい観測値の存在を示します。

読み取りのポイントは、単に「中央値が高い/低い」だけでなく、ばらつきと偏り(分布の非対称性)まで含めて比較することです。例えば次のように解釈します。

  • 中央値の比較:箱の中の線が上にあるグループほど、値の中心が大きい傾向。
  • ばらつきの比較:箱(IQR)が大きいほど、データが散らばっていて安定しにくい可能性。
  • 分布の偏り(歪み):中央値が箱の上側に寄っていたり、ひげの長さが上下で極端に違う場合、分布が片側に偏っているサイン。
  • 外れ値の有無:点が多い場合は、特殊ケースが頻発している、計測ミスが混ざっている、あるいは実態として極端値が出やすい、などの可能性。

Pythonで箱ひげ図を描く場合、Matplotlibではboxplotを使います。以下は最小例です(複数グループ比較)。

import matplotlib.pyplot as plt

a = [10, 11, 12, 13, 14, 30]  # 外れ値が混ざる例
b = [8, 9, 9, 10, 10, 11, 12]
c = [15, 15, 16, 17, 18, 18, 19]

plt.figure(figsize=(6, 4))
plt.boxplot([a, b, c], labels=["A", "B", "C"])
plt.ylabel("value")
plt.title("Boxplot comparison")
plt.show()

箱ひげ図を比較するときは、「箱が重なっているから差がない」と早合点しないことも重要です。箱ひげ図は分布の概要を示す可視化であり、データ数が少ない場合や外れ値が多い場合は形が大きく変わります。まずは中央値・IQR・ひげ・外れ値をセットで読み取り、グループごとの特徴を整理すると、python グラフとしての箱ひげ図を意思決定に活かしやすくなります。

2次元データの可視化(メッシュ・等高線)

python+matplotlib+visualization

「python グラフ」で扱うデータが1次元(xとy)だけとは限りません。たとえば、温度分布・標高・誤差関数の形状など、xとyの組み合わせごとに値zが決まる2次元データは頻出です。こうしたデータは、色で値を表す「2次元メッシュ表示」や、同じ値を線で結ぶ「等高線(contour)」で可視化すると、全体の傾向や局所的な変化が一目で分かります。

2次元メッシュ表示の基本

2次元メッシュ表示は、格子状(グリッド)に並んだz値を色で表現する可視化です。Matplotlibでは主に pcolormeshimshow が使われますが、座標(x,y)を明示して扱える点で pcolormesh は2次元データに相性が良いです。

基本の流れは次のとおりです。

  • x軸・y軸の値を用意する(例:等間隔の配列)
  • np.meshgrid で2次元の座標配列(X, Y)を作る
  • X, Yから計算したZ(または観測データの格子)を色で表示する
  • カラーバー(凡例)で色と値の対応を示す
import numpy as np
import matplotlib.pyplot as plt

# 2次元グリッド(座標)を作成
x = np.linspace(-3, 3, 200)
y = np.linspace(-3, 3, 200)
X, Y = np.meshgrid(x, y)

# 例:2次元関数からZを生成(山と谷が分かりやすい形)
Z = np.sin(X) * np.cos(Y)

fig, ax = plt.subplots()

# 2次元メッシュ表示(色でZの値を表す)
m = ax.pcolormesh(X, Y, Z, shading="auto", cmap="viridis")

ax.set_xlabel("x")
ax.set_ylabel("y")

# 値のスケールを示すカラーバー
fig.colorbar(m, ax=ax, label="z")

plt.show()

メッシュ表示を見やすくする際に意識したいポイントです。

  • shadingshading="auto" を指定すると格子サイズと整合しやすく、警告も避けやすい
  • cmap(カラーマップ):連続値には viridis など視認性の高いものが無難
  • カラーバー:色だけでは値が分からないため、fig.colorbar を付けるのが基本

等高線(contour)の描画方法

等高線(contour)は、同じz値の地点を線で結ぶことで、2次元データの「形」を直感的に読める可視化です。標高図の等高線と同じイメージで、ピークの位置や傾き、谷の方向などが把握しやすくなります。Matplotlibでは主に contour(線のみ)と contourf(塗りつぶし)が使われます。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-3, 3, 250)
y = np.linspace(-3, 3, 250)
X, Y = np.meshgrid(x, y)

Z = np.sin(X) * np.cos(Y)

fig, ax = plt.subplots()

# 等高線(線)を描画:levelsで本数(段数)を調整
cs = ax.contour(X, Y, Z, levels=10, cmap="plasma")

# 等高線に値ラベルを付ける(読み取りやすくなる)
ax.clabel(cs, inline=True, fontsize=8)

ax.set_xlabel("x")
ax.set_ylabel("y")

plt.show()

より面で把握したい場合は、塗りつぶし等高線の contourf が便利です。メッシュ表示と同様にカラーバーを付けると、値の対応が明確になります。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-3, 3, 250)
y = np.linspace(-3, 3, 250)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)

fig, ax = plt.subplots()

cf = ax.contourf(X, Y, Z, levels=20, cmap="viridis")
fig.colorbar(cf, ax=ax, label="z")

ax.set_xlabel("x")
ax.set_ylabel("y")

plt.show()

等高線を実務で使うときの調整ポイントを押さえておくと、同じ「python グラフ」でも読みやすさが大きく変わります。

  • levels:段数が少なすぎると粗く、多すぎると線が密になり読みにくい。まずは10〜20程度から調整
  • clabel:線に数値を載せると、どの高さ(値)かが即読できる
  • contour と contourf の使い分け:形状を線で追いたいなら contour、面の分布を見たいなら contourf

グラフの見た目を整える(タイトル・軸・凡例・装飾)

python+matplotlib+visualization

Pythonでグラフを作ったあと、「情報は伝わるが見栄えがいまいち」という状態はよくあります。Matplotlibでは、タイトル・軸・凡例・装飾・サイズなどを少し調整するだけで、読み手にとって理解しやすい「伝わるpython グラフ」に仕上げられます。ここでは、見た目を整えるための主要な調整ポイントをまとめて紹介します。

タイトルと軸ラベルを設定する

タイトルと軸ラベルは、グラフが何を示すのかを瞬時に伝えるための必須要素です。特に複数の図を扱う場合、ラベルがないと後から見返したときに意図が読み取れなくなります。

Matplotlibでは、Axes(ax)に対して設定するのが基本です。単位(例:秒、円、%)も軸ラベルに含めると、誤解を防げます。

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

ax.plot([1, 2, 3], [2, 3, 5])

ax.set_title("売上推移(2025年)")
ax.set_xlabel("月")
ax.set_ylabel("売上(万円)")

plt.show()

文字が詰まって見える場合は、フォントサイズや余白も合わせて調整すると視認性が上がります。

ax.set_title("売上推移(2025年)", fontsize=14, pad=10)
ax.set_xlabel("月", fontsize=12, labelpad=8)
ax.set_ylabel("売上(万円)", fontsize=12, labelpad=8)

軸の設定(目盛り・範囲・スケール)

軸の調整は「読み取りやすさ」を左右します。データの変化が小さいのに範囲が広すぎると差が見えませんし、逆に範囲を詰めすぎると誇張して見えることもあります。目的に合わせて、範囲・目盛り・スケールを整えましょう。

範囲(limits)の設定

ax.set_xlim(1, 12)     # x軸の表示範囲
ax.set_ylim(0, 100)    # y軸の表示範囲

目盛り(ticks)の設定

重要な区切り(四半期、10刻み、曜日など)に合わせて目盛りを明示すると、python グラフの読み取りがスムーズになります。

ax.set_xticks([1, 3, 6, 9, 12])
ax.set_yticks([0, 20, 40, 60, 80, 100])

目盛りラベル(tick labels)の調整

ax.set_xticklabels(["1月", "3月", "6月", "9月", "12月"])
ax.tick_params(axis="x", labelrotation=0)   # 斜め表示にしたい場合は角度を指定

スケールの変更(対数など)

桁の差が大きいデータ(アクセス数、金額、指数など)では対数スケールが有効です。

ax.set_yscale("log")

グリッド線の表示と調整

グリッド線は、値の読み取りを助ける一方で、濃すぎると主役の線や点を邪魔します。「薄く・必要最小限」を意識すると、上品で見やすいpython グラフになります。

ax.grid(True)  # まずは表示

線の種類・濃さ・対象軸を調整すると、視認性が上がります。

ax.grid(True, which="major", axis="both", linestyle="--", linewidth=0.8, alpha=0.4)

補助目盛りまで含めたい場合は which を使い分けます(ただし細かくしすぎると逆効果です)。

ax.minorticks_on()
ax.grid(True, which="minor", linestyle=":", linewidth=0.5, alpha=0.2)

凡例の表示・位置・枠線の調整

複数系列を描くとき、凡例(legend)がないと比較が成立しません。系列名はlabelで付け、凡例はlegend()で表示します。

ax.plot([1, 2, 3], [2, 3, 5], label="商品A")
ax.plot([1, 2, 3], [1, 4, 4], label="商品B")

ax.legend()

凡例の位置は、データと重ならない場所に移動します。Matplotlibのlocを使うと定番位置を指定できます。

ax.legend(loc="upper left")

枠線や背景を調整すると、資料向けに整った印象になります(背景を透明にして重なりを減らす、枠線を細くするなど)。

ax.legend(
    loc="best",
    frameon=True,
    framealpha=0.9,
    edgecolor="0.8"
)

線種・線幅・色・マーカーなどスタイル変更

スタイルは「見栄え」だけでなく、「区別のしやすさ」に直結します。色だけに頼ると、印刷や色覚多様性の観点で判別しづらいことがあるため、線種やマーカーも併用するのが実務的です。

基本的なスタイル指定

ax.plot(
    [1, 2, 3], [2, 3, 5],
    color="tab:blue",
    linewidth=2.0,
    linestyle="-",
    marker="o",
    markersize=6,
    label="商品A"
)

系列ごとに「色+線種+マーカー」を変える

ax.plot([1, 2, 3], [2, 3, 5], color="tab:blue", linestyle="-", marker="o", label="商品A")
ax.plot([1, 2, 3], [1, 4, 4], color="tab:orange", linestyle="--", marker="s", label="商品B")

透明度(alpha)で重なりを見やすくする

ax.plot([1, 2, 3], [2, 3, 5], alpha=0.8)

線が多いときは、太さを揃えつつ強調したい系列だけ太くするなど、「主役と脇役」を作ると情報が整理されます。

グラフサイズと解像度(dpi)の調整

同じpython グラフでも、掲載先がスライドなのか、Web記事なのか、印刷なのかで最適なサイズ・解像度は変わります。Matplotlibでは、図の大きさ(インチ)と解像度(dpi)を指定して、意図通りの出力に整えられます。

表示サイズ(figure size)の指定

fig, ax = plt.subplots(figsize=(8, 4))  # 横8インチ × 縦4インチ

解像度(dpi)の指定

fig, ax = plt.subplots(figsize=(8, 4), dpi=150)

保存用途ではdpiが効きます。細い線や小さな文字が潰れる場合は、dpiを上げると改善しやすいです。

fig.savefig("graph.png", dpi=200)

一方で、dpiを上げすぎるとファイルサイズが大きくなり、Web表示が重くなることがあります。用途(資料・ブログ・印刷)に合わせて適切なバランスに調整するのがポイントです。

複数グラフのレイアウト(並べる・組み合わせる)

python+matplotlib+subplot

Pythonでグラフを作る場面では、「1枚の図に複数のグラフを並べて比較したい」「異なる種類のグラフを組み合わせて1つのメッセージを伝えたい」といったニーズがよくあります。ここでは、python グラフ作成で頻出の2パターンとして、サブプロットによる配置と、同一図への重ね描きを解説します。

サブプロットで複数のグラフを配置する

サブプロット(subplot)は、1つのFigure(図)の中に複数のAxes(描画領域)を作り、グラフを「並べる」ための基本機能です。比較・推移・分布などを同じスケール感で見せたいときに特に有効です。

もっとも使いやすいのが plt.subplots() です。行×列でAxesを作成し、各Axesに対して個別に描画します。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1, 6)
y1 = np.array([2, 3, 5, 4, 6])
y2 = np.array([1, 2, 2, 3, 5])

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))

# 左:折れ線
axes[0].plot(x, y1, marker="o")
axes[0].set_title("Line")
axes[0].set_xlabel("x")
axes[0].set_ylabel("value")

# 右:棒グラフ
axes[1].bar(x, y2)
axes[1].set_title("Bar")
axes[1].set_xlabel("x")
axes[1].set_ylabel("value")

plt.tight_layout()
plt.show()

サブプロット配置で押さえておくと便利なポイントは次の通りです。

  • Axesを配列として扱うaxes[0]axes[1] のように、描画先を明示できて管理しやすい
  • 図全体のサイズ調整figsize で横長・縦長などレイアウトに合わせて調整
  • 余白の自動調整plt.tight_layout() でタイトルやラベルの重なりを軽減

また、縦方向に並べたい場合は nrows=2, ncols=1 のように指定します。行列が増えるほど比較がしやすい一方で、文字が詰まりやすくなるため、figsize の拡大と tight_layout() の併用が実務的です。

fig, axes = plt.subplots(2, 1, figsize=(8, 6))
axes[0].plot(x, y1)
axes[1].plot(x, y2)
plt.tight_layout()
plt.show()

異なる種類のグラフを同じ図に重ねる

複数系列を単に並べるのではなく、「同じAxesに重ねて」表示することで、関係性を直感的に伝えられます。たとえば、棒グラフ(量)と折れ線(推移)を同じ図で見せる構成は定番です。

同じAxesに重ねる場合は、同一のAxesに対して異なる描画メソッドを順に呼び出します。次の例は、棒グラフの上に折れ線を重ねた python グラフ の基本形です。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1, 6)
bar = np.array([10, 14, 9, 12, 15])
line = np.array([11, 13, 10, 11, 16])

fig, ax = plt.subplots(figsize=(8, 4))

ax.bar(x, bar, alpha=0.7, label="Bar")
ax.plot(x, line, color="C1", marker="o", linewidth=2, label="Line")

ax.set_title("Overlay: bar + line")
ax.set_xlabel("x")
ax.set_ylabel("value")
ax.legend()

plt.tight_layout()
plt.show()

重ね描きで見やすさを保つコツは、役割に応じて視覚要素を分けることです。

  • 透過(alpha)を使う:棒や塗りつぶしは alpha で下の要素が見えるようにする
  • 線は太さ・マーカーで強調:折れ線は linewidthmarker で判別しやすくする
  • 凡例(legend)で意味を明確化:重ねるほど読者が迷うためラベルは必須

さらに「単位が違うデータ」を同じ図で見せたい場合は、右側のy軸(第2軸)を使う方法があります。棒は件数、折れ線は割合…のようにスケールが異なるときに有効です。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1, 6)
count = np.array([120, 180, 150, 210, 190])     # 件数
rate = np.array([0.20, 0.28, 0.22, 0.30, 0.26]) # 割合

fig, ax1 = plt.subplots(figsize=(8, 4))
ax2 = ax1.twinx()  # 右軸

ax1.bar(x, count, alpha=0.7, label="Count")
ax2.plot(x, rate, color="C1", marker="o", linewidth=2, label="Rate")

ax1.set_xlabel("x")
ax1.set_ylabel("count")
ax2.set_ylabel("rate")

# 凡例は2軸分をまとめる
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1 + h2, l1 + l2, loc="upper left")

plt.tight_layout()
plt.show()

第2軸は便利な一方で、軸が増えると誤読のリスクも高まります。ラベル(set_ylabel)を明確にし、色を系列と対応させるなど、視認性と説明性をセットで設計するのがポイントです。

NumPyと組み合わせて関数・データを描画する

python+matplotlib+numpy

Pythonでグラフを描くとき、Matplotlibだけでも描画は可能ですが、データ生成や前処理をNumPyで行うと「配列でまとめて計算→そのままプロット」という流れが作れます。特に関数の値をまとめて計算して線で結ぶグラフは、NumPyのベクトル演算(要素ごとの計算)がそのまま活きるため、短いコードで見通しよく書けます。このセクションでは、python グラフ作成でよく使うNumPy配列の作り方から、数学関数、関数グラフ、媒介変数曲線、2系列比較までを一気に押さえます。

NumPy配列の作り方と基本計算

NumPyは数値計算に強いライブラリで、グラフ用のx軸データ(等間隔の点)や、計算したy値を効率的に扱えます。まずは「配列を作る」「要素ごとに計算する」という2点を押さえると、関数のグラフ化がスムーズです。

代表的な配列作成は次のとおりです。

  • np.array([...]):Pythonのリストから配列を作る
  • np.arange(start, stop, step):等間隔の値(stopは含まない)
  • np.linspace(start, stop, num):区間をnum個に分割(stopを含む)
  • np.zeros(n)/np.ones(n):0や1で埋めた配列

NumPy配列は基本的に「要素ごとの演算」ができます。例えば x が配列なら x**2 は各要素を二乗した配列になります。グラフ用データを作る上で非常に重要なポイントです。

import numpy as np

# 配列の作成
x1 = np.array([0, 1, 2, 3, 4])
x2 = np.arange(0, 5, 1)           # 0,1,2,3,4
x3 = np.linspace(0, 4, 5)         # 0,1,2,3,4(5分割)

# 基本計算(要素ごと)
y_add = x1 + 10                   # 10,11,12,13,14
y_pow = x1**2                     # 0,1,4,9,16
y_mix = 2 * x1 + 3                # 3,5,7,9,11

関数グラフでは、横軸となる xnp.linspace で細かく取り、y = f(x) をベクトル演算で一気に求める、という形が定番です。

数学関数(三角関数・対数など)を使ったデータ生成

関数を使ったpython グラフでは、NumPyの数学関数がそのまま活躍します。NumPyの np.sinnp.log は「配列を渡すと配列で返る」ため、点列生成に最適です。

  • 三角関数:np.sin, np.cos, np.tan(角度はラジアン)
  • 指数・対数:np.exp, np.log, np.log10
  • 平方根・絶対値:np.sqrt, np.abs

例えば、0〜2πの範囲でサイン波のデータを作るなら次のように書けます。

import numpy as np

x = np.linspace(0, 2*np.pi, 400)
y_sin = np.sin(x)
y_cos = np.cos(x)

対数を使うときは、入力が0以下にならないように範囲を設計します(例:x を 0 より大きいところから始める)。

import numpy as np

x = np.linspace(0.1, 10, 300)  # 0以下を避ける
y_log = np.log(x)
y_log10 = np.log10(x)

この「データの定義域(入力できる範囲)」を意識すると、計算結果が naninf になって線が途切れる、といった問題を避けやすくなります。

関数のグラフ化(例:放物線・サイン波)

関数のグラフ化は、(1) xを用意して (2) yを計算し (3) plot で描く、という流れです。NumPyを使うと、for文で点を1つずつ計算しなくても、配列のまま計算してそのまま渡せます。

まずは放物線 y = x^2 の例です。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-3, 3, 400)
y = x**2

plt.plot(x, y)
plt.show()

次に、サイン波 y = sin(x) を描く例です。周期関数は点の数が少ないとギザギザに見えるため、linspace の分割数を増やすと滑らかになります。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x)

plt.plot(x, y)
plt.show()

同じ要領で、振幅や周波数を変えた波形も簡単に作れます(例:y = A*sin(ωx))。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 400)
A = 2.0
omega = 3.0
y = A * np.sin(omega * x)

plt.plot(x, y)
plt.show()

このように「パラメータを変えるだけで形が変わる」関数は、NumPy×Matplotlibでのpython グラフ作成と相性が良く、試行錯誤もしやすいのが特徴です。

媒介変数による曲線の描画(例:円・リサジュー)

媒介変数(パラメータ)で表す曲線は、xとyを同じ変数 t で定義し、(x(t), y(t)) を描く方法です。通常の「y=f(x)」では表しづらい図形(円など)をきれいに描けます。

円は次のように表せます。

  • x = r cos(t)
  • y = r sin(t)
import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(0, 2*np.pi, 400)
r = 1.0
x = r * np.cos(t)
y = r * np.sin(t)

plt.plot(x, y)
plt.show()

リサジュー曲線は、周波数比や位相差で形が変わる典型例です。

import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(0, 2*np.pi, 2000)

a = 3  # x側の周波数
b = 2  # y側の周波数
delta = np.pi / 2  # 位相差

x = np.sin(a * t + delta)
y = np.sin(b * t)

plt.plot(x, y)
plt.show()

媒介変数曲線では、t の刻み(点の密度)が見た目に直結します。複雑な曲線ほど t の分割数を増やすと滑らかになります。

2系列の比較プロットの作り方

同じxに対して2つのy系列を重ねて描くと、関数の違いやパラメータ違いを比較できます。NumPyでそれぞれの系列を生成し、plot を2回呼ぶだけでOKです。

例として、sin(x)cos(x) を比較します。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 400)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, label="sin(x)")
plt.plot(x, y2, label="cos(x)")
plt.show()

また、「同じ関数でパラメータだけ変えた2系列」も比較の定番です。例えば周波数違いのサイン波を重ねると、変化の速さの違いが視覚的に分かります。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 400)
y1 = np.sin(1.0 * x)
y2 = np.sin(3.0 * x)

plt.plot(x, y1, label="sin(x)")
plt.plot(x, y2, label="sin(3x)")
plt.show()

比較プロットでは、2系列が同じ座標系に乗るように「xの範囲・点数を揃える」ことが重要です。NumPyでxを共通化しておくと、ズレのない比較ができます。

アニメーションで動くグラフを作る

python+matplotlib+animation

Python グラフを「動く」形で見せたい場合は、Matplotlibのアニメーション機能を使うのが定番です。時系列の推移、シミュレーションの更新、逐次学習の損失推移など、静止画では伝わりにくい変化を直感的に表現できます。ここでは、アニメーション作成で押さえるべき基本(更新関数・保存)に絞って解説します。

アニメーション作成の基本(更新関数・保存)

Matplotlibでアニメーションを作る中心は matplotlib.animation.FuncAnimation です。ポイントは大きく2つで、「何を描くか(初期化)」と「各フレームで何を更新するか(更新関数)」を分けて考えることです。更新対象は線(Line2D)や散布図(PathCollection)などの“アーティスト”で、フレームごとにデータを書き換えて表示を更新します。

最小構成の流れは次の通りです。

  • Figure/Axesを用意し、更新したい要素(例:折れ線)を一度作って保持する
  • 初期表示用の関数(init)で空データや初期状態をセットする
  • 更新関数(update)でフレーム番号に応じてデータを差し替える
  • FuncAnimationframes(フレーム数)や interval(更新間隔ms)を渡して実行する
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# データ(例:サイン波が右へ流れる)
x = np.linspace(0, 2*np.pi, 200)

fig, ax = plt.subplots()
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1.2, 1.2)

line, = ax.plot([], [], lw=2)  # 更新対象(アーティスト)を先に作る

def init():
    line.set_data([], [])
    return line,

def update(frame):
    # frame: 0,1,2,... と増える(framesで指定)
    y = np.sin(x + frame * 0.1)
    line.set_data(x, y)
    return line,

ani = FuncAnimation(
    fig,
    update,
    frames=100,
    init_func=init,
    interval=50,
    blit=True
)

plt.show()

update の返り値に「更新したアーティスト」をタプルで返すのが基本です。特に blit=True を使う場合、戻り値が正しくないと描画が更新されない・ちらつくなどの原因になります(環境によっては blit=False の方が安定する場合もあります)。

アニメーションの保存は、用途に応じてGIFまたはMP4がよく使われます。保存にはライター(writer)が必要で、環境により追加インストールが必要になる点も押さえておきましょう。

  • GIF:PillowWriter が比較的手軽(ファイル共有もしやすい)
  • MP4:ffmpeg を使うことが多い(高画質・軽量になりやすい)
from matplotlib.animation import PillowWriter

# GIFとして保存(例)
ani.save("animation.gif", writer=PillowWriter(fps=20))
# MP4として保存(例:ffmpegが必要)
ani.save("animation.mp4", writer="ffmpeg", fps=20, dpi=150)

保存時は次のパラメータ調整が効きます。

  • fps:1秒あたりのコマ数。大きいほど滑らかだがファイルサイズも増えやすい
  • dpi:解像度。プレゼン用途ならやや高め、Web用途ならバランス重視
  • intervalfps の整合:表示と保存で体感速度が変わることがあるため、意図に合わせて揃える

このように、Python グラフのアニメーションは「更新関数でデータを差し替える」設計さえ理解できれば、折れ線だけでなく散布図・ヒートマップなどにも同じ発想で応用できます。まずは更新対象を1つに絞った小さな例から作り、保存までの一連の流れを固めるのが近道です。

よくあるつまずきとトラブルシューティング

python+matplotlib+visualization

Pythonでグラフを描く際(特にMatplotlibを使う場面)は、「日本語が表示できない」「保存した画像の見た目が崩れる」「環境によって急にエラーが出る」といったつまずきが起きやすいです。ここでは、Python グラフ作成でよく遭遇する代表的なトラブルと、再現性高く解決するための対処法をまとめます。

日本語が文字化けする場合の対処

タイトルや軸ラベル、凡例を日本語にしたときに「□(豆腐)」や「?」になる原因の多くは、Matplotlibが利用できる日本語フォントを見つけられていないことです。OSごとに標準フォントが異なるため、同じコードでも環境差が出やすいポイントでもあります。

対処の基本は、使用フォントを明示することです。まずは現在の環境で利用可能なフォントを確認し、確実に存在するフォント名を指定します。

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# 利用可能フォントの一部を確認(環境によって数が多いので注意)
fonts = sorted({f.name for f in fm.fontManager.ttflist})
print(fonts[:50])

フォント名が分かったら、rcParamsで日本語フォントを指定します。

import matplotlib.pyplot as plt

plt.rcParams["font.family"] = "IPAexGothic"  # 例:環境に存在する日本語フォント名に置き換え
plt.plot([1, 2, 3], [2, 1, 3])
plt.title("売上推移(日本語テスト)")
plt.xlabel("月")
plt.ylabel("売上")
plt.show()

また、グラフ中にマイナス記号が「−」ではなく四角や別の記号になる場合は、以下の設定が有効です。

plt.rcParams["axes.unicode_minus"] = False

それでも解決しない場合は、次をチェックしてください。

  • フォント名のスペル:存在しないフォント名を指定していると、別フォントにフォールバックして文字化けします。
  • 実行環境:DockerやCIなどの最小環境では日本語フォント自体が入っていないことがあります。その場合は日本語フォントを導入したうえで指定が必要です。
  • キャッシュ影響:フォント追加後に反映されないときは、環境再起動やフォントキャッシュ更新が必要になる場合があります。

画像保存時にレイアウトが崩れる場合の対処

画面表示では問題ないのに、PNGなどで保存すると「タイトルやラベルが切れる」「凡例がはみ出す」「余白が不自然」といったレイアウト崩れが起きることがあります。これは保存時のバウンディングボックス計算や余白設定が原因になりがちです。

まず試したい定番は、tight_layoutbbox_inches=”tight”の組み合わせです。

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([1, 2, 3], [2, 1, 3])
ax.set_title("タイトルが長い場合の例:Python グラフ保存")
ax.set_xlabel("横軸ラベル(長め)")
ax.set_ylabel("縦軸ラベル(長め)")
ax.legend(["系列A"], loc="upper left")

fig.tight_layout()
fig.savefig("graph.png", dpi=200, bbox_inches="tight")

複数サブプロットで詰まりやすい場合は、constrained_layoutが効くこともあります。

import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(8, 3), constrained_layout=True)
axes[0].plot([1, 2, 3], [1, 2, 1])
axes[0].set_title("左")
axes[1].plot([1, 2, 3], [2, 1, 2])
axes[1].set_title("右")

fig.savefig("subplots.png", dpi=200)

それでも凡例や注釈が図の外に配置されるケースでは、保存時に切れることがあります。次の観点で調整してください。

  • 図のサイズを確保figsizeを大きくする(情報量に対してキャンバスが小さいと崩れやすい)。
  • 凡例の位置locbbox_to_anchorで図の内側に収める。
  • 余白の明示調整plt.subplots_adjust(left=..., right=..., top=..., bottom=...)で最終調整する。
  • DPIの影響:高dpiで文字が大きく見え、結果としてはみ出すことがあるため、dpiとfigsizeのバランスを取る。

エラーになりやすいポイント(環境差・依存関係)

Pythonでグラフ作成が急に動かなくなる原因は、コードの誤りだけでなく環境差依存関係にあることが少なくありません。特に「ローカルでは動くのに別PC/サーバーで落ちる」パターンはここが原因になりやすいです。

代表的なエラー要因と対処を整理します。

  • バックエンド関連のエラー(GUIがない環境)

    サーバーやコンテナなどディスプレイのない環境でplt.show()を使うと、バックエンドが原因でエラーになることがあります。基本方針は「表示せず保存に寄せる」ことです。必要に応じてバックエンドを切り替えます。

    import matplotlib
    matplotlib.use("Agg")  # 画面表示なしでファイル保存向け
  • インストール済みだが import できない/バージョン不整合

    仮想環境が混在していると「pipで入れたのにimportできない」が起きます。まずは実行中Pythonとpipの対応を確認します。

    python -c "import sys; print(sys.executable)"
    python -m pip show matplotlib

    チーム開発では、依存を固定したrequirements.txtやロックファイル(利用ツールに応じたもの)で環境差を減らすのが有効です。

  • フォント依存(日本語表示の失敗)

    前述の通り、OSや最小環境では日本語フォントが入っていない場合があります。フォントを追加したうえでplt.rcParams["font.family"]で明示するのが安全です。

  • 保存先パス・権限・カレントディレクトリの問題

    savefigでエラーになる場合、保存先ディレクトリが存在しない/書き込み権限がない/想定と違う場所を見ているケースがあります。相対パスではなく一度絶対パスで切り分けると原因特定が早くなります。

  • 依存ライブラリ(NumPy等)との組み合わせでの型・形状エラー

    配列の長さ不一致(xとyの要素数が違う)などは典型的です。特に前処理を挟むと起きやすいため、プロット直前にshape/lenを確認する習慣が有効です。

    print(len(x), len(y))

トラブル時は「①再現条件(どの環境で、どのコードで)」「②エラーメッセージ全文」「③Matplotlib/ Pythonのバージョン」をセットで整理すると、Python グラフ周りの問題は切り分けが一気に進みます。

まとめ:目的別のおすすめグラフと次のステップ

python+matplotlib+visualization

Pythonでグラフを描けるようになると、分析結果の「伝わりやすさ」が一気に上がります。ただし、可視化は“多機能なほど良い”わけではなく、目的に合うグラフを選び、必要最小限の操作を確実に身につけるのが近道です。ここでは「まず何を覚えるべきか」と「次に伸ばす方向」を、目的別に整理して締めくくります。

まず覚えるべき最小セット

最初は、Python グラフの学習範囲を絞り込み、「どのデータにどのグラフを当てるか」と「最低限の体裁を整える」をセットで覚えるのがおすすめです。以下の“最小セット”を押さえるだけで、日常的なレポート・分析の可視化はかなりカバーできます。

  • 時系列・推移を見たい:折れ線グラフ

    売上の推移、センサー値の変化、学習曲線など「時間とともにどう変わったか」を伝えるのに向きます。ポイントは、系列が増えたら凡例を付け、線色・線種で区別して“読み分けられる状態”にすることです。

  • カテゴリ別に比較したい:棒グラフ

    部門別・商品別・都道府県別など、カテゴリ間の大小比較に強いのが棒グラフです。比較が目的なら、並び順(降順など)を意識すると読み手の理解が速くなります。

  • 関係性・相関の気配を見たい:散布図

    「広告費と売上」「身長と体重」のように、2変数の関係をざっくり掴むのに有効です。点の重なりが多い場合は、サイズや透明度(alpha)を調整して密度感が分かるようにします。

  • 分布の形を知りたい:ヒストグラム

    平均だけでは見えない“偏り”“ばらつき”“外れ値っぽさ”を把握するのに役立ちます。まずはビン数を変えながら、分布の印象が不自然に変わらない粒度を探すのが実務的です。

  • 複数グループの分布比較をしたい:箱ひげ図

    部署A/B、施策前後など、グループ間の分布差を比較したいときに便利です。「中央値」「ばらつき」「外れ値」を一度に示せるため、説得力のある説明につながります。

そして、どのグラフにも共通して“必須で覚えたい”体裁の要素があります。

  • タイトル・軸ラベル:何のデータか、単位は何かを明確にする

  • 凡例:複数系列の意味を迷わせない

  • 保存(書き出し):資料に貼れる状態で出力する

この最小セットを押さえると、「とりあえずPythonでグラフを作る」段階から、「目的に合うPython グラフを素早く作る」段階へ移れます。

次に学ぶと良い可視化ライブラリ・発展テーマ

最小セットに慣れてきたら、次は“表現力”か“伝達力”を伸ばす学びに進むと伸びが大きいです。作りたいアウトプット(社内報告、分析ダッシュボード、学術用途など)に応じて、以下を選ぶのがおすすめです。

  • 見た目を整えた統計可視化を素早く作りたい:Seaborn

    散布図+回帰のような統計的な見せ方や、カテゴリ別の分布比較などを短いコードで表現しやすいのが特長です。「分析の意図が伝わる形」を手早く作りたい場合に次の一手になります。

  • インタラクティブに探索・共有したい:Plotly

    ホバーで値を見せる、ズームする、凡例クリックで系列をオンオフするなど、操作できるPython グラフを作りたいなら有力です。分析結果を“触って理解してもらう”用途に向きます。

  • データ加工〜可視化の流れを短くしたい:Pandasのプロット活用

    表データを扱うことが多いなら、DataFrameから素早く描ける流れを固めると効率が上がります。まずは「集計→そのまま描画→必要に応じて調整」という運用にすると、手戻りが減ります。

ライブラリ以外の“発展テーマ”としては、次の方向性が実務で効きます。

  • 複数グラフのレイアウト設計:比較・俯瞰を1枚で伝える(小さな複数図、並列比較など)

  • 2次元データの表現:ヒートマップや等高線など、面で傾向を示す可視化

  • アニメーション:時系列の変化やシミュレーション結果を動きで理解させる

  • 再現性とテンプレ化:配色・フォント・サイズを定型化して、毎回の品質を安定させる

最終的には、「何を伝えたいか」→「適切なグラフ種類」→「読み手にとって誤解のない体裁」という順で選べる状態がゴールです。Python グラフは手段なので、次に学ぶ内容も“作りたい成果物”から逆算して選ぶと、無駄なくスキルが積み上がります。