データをグラフで可視化できると、数字の「傾向」や「違い」が直感的に分かります。
本記事では、Python初心者の方でもすぐに使えるように、MatplotlibとSeabornで折れ線・棒・散布図を作る基本を、日本語表示に強い設定(日本語フォントとマイナス記号)を含めて丁寧に解説します。
Python初心者向けの準備と環境
必要なライブラリのインストール
可視化にはMatplotlibとSeabornを使います。
データ整形にはpandas、数値生成にNumPy、日本語の文字化け防止にjapanize_matplotlibを使います。
Jupyterを利用する場合はJupyterLabも入れておくと便利です。
# 仮想環境の利用を推奨します(例: venvやconda)
# 必要ライブラリのインストール
pip install matplotlib seaborn pandas numpy japanize-matplotlib jupyterlab
# 出力例(一部)
# Successfully installed matplotlib-3.x seaborn-0.12.x pandas-2.x numpy-1.x japanize-matplotlib-1.1.3 ...
バージョンの確認
ライブラリのバージョンが古いと動作が異なることがあります。
確認しておくと安心です。
import matplotlib
import seaborn as sns
import pandas as pd
import numpy as np
print("matplotlib:", matplotlib.__version__)
print("seaborn :", sns.__version__)
print("pandas :", pd.__version__)
print("numpy :", np.__version__)
matplotlib: 3.10.6
seaborn : 0.13.2
pandas : 2.3.2
numpy : 2.3.3
日本語の文字化け対策
Matplotlibは標準設定だと日本語が文字化けします。
japanize_matplotlibを読み込むだけで、日本語対応のフォントとマイナス記号の設定が自動で適用されます。
以降のサンプルでは毎回読み込みます。
# 日本語表示テスト用の最小コード
import matplotlib.pyplot as plt
import japanize_matplotlib # これだけで日本語対応フォントが有効化されます
# マイナス記号が豆腐(□)にならないようにするための保険
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False
plt.figure(figsize=(4, 3))
plt.title("日本語のタイトル")
plt.xlabel("横軸(サンプル)")
plt.ylabel("縦軸(サンプル)")
plt.plot([-2, -1, 0, 1, 2], [1, 2, 0, 2, 1], marker="o")
plt.tight_layout()
plt.show()
print("日本語とマイナス記号の表示テストが完了しました。")
日本語とマイナス記号の表示テストが完了しました。

環境によっては初回実行時にフォントキャッシュが作られます。
数秒かかることがあります。
基本のインポートと表示の流れ
グラフの基本は「データを用意 → 図形を描く → 体裁(タイトル等)を整える → 表示または保存」です。
最小の流れを確認します。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import japanize_matplotlib # 日本語対応
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False # マイナス記号対策
# Seabornのテーマ(後で上書き可能)
# フォントの再設定が必要になるので注意(日本語が文字化けします)
sns.set_theme(style="whitegrid")
mpl.rcParams['font.family'] = 'IPAexGothic' # 日本語対応フォント
# サンプルデータ
x = np.arange(6) # 0~5
y = np.array([5, 3, 4, 7, 6, 8])
plt.figure(figsize=(5, 3))
plt.plot(x, y, marker="o", label="サンプル系列")
plt.title("最小構成の折れ線グラフ")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend()
plt.tight_layout()
plt.show()
print("基本の表示フローを確認しました。")
基本の表示フローを確認しました。
サンプルデータの用意
以降の解説で使い回せるように、月別の売上データと散布図用の疑似データを用意します。
import numpy as np
import pandas as pd
# 月(1~6月)
months = np.arange(1,
7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
# 地域カテゴリ(散布図の色分けに使う)
regions = np.array(["東", "西", "南", "北", "東", "西"])
# 月ごとに軽いノイズを入れた座標(散布図)
rng = np.random.default_rng(42)
x_scatter = months + rng.normal(0, 0.15, size=months.size)
y_scatter = sales_A * 0.8 + rng.normal(0, 5, size=months.size)
# DataFrameにまとめ
df = pd.DataFrame({
"month": months,
"sales_A": sales_A,
"sales_B": sales_B,
"region": regions,
"x_scatter": x_scatter,
"y_scatter": y_scatter
})
# Seaborn向けに縦長形式へ(折れ線や棒の色分けに便利)
df_long = df.melt(id_vars=["month", "region"],
value_vars=["sales_A", "sales_B"],
var_name="store",
value_name="sales")
print(df.head(3))
print(df_long.head(3))
month sales_A sales_B region x_scatter y_scatter
0 1 50 40 東 1.045556 39.653835
1 2 65 55 西 2.074435 46.310879
2 3 80 60 南 2.873789 64.938111
month region store sales
0 1 東 sales_A 50
1 2 西 sales_A 65
2 3 南 sales_A 80
ポイント: Seabornはdf_long
のような「縦長」(tidy)データと相性が良いです。
Matplotlibで折れ線・棒グラフ・散布図
折れ線グラフ(plot)の基本
2系列の折れ線と凡例
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
import numpy as np
# 月(1~6月)
months = np.arange(1,
7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
mpl.rcParams["axes.unicode_minus"] = False
# 前セクションで作成した months, sales_A, sales_B を利用
plt.figure(figsize=(6, 4))
plt.plot(months, sales_A, marker="o", color="C0", label="A店")
plt.plot(months, sales_B, marker="s", color="C1", label="B店")
plt.title("月別売上の推移")
plt.xlabel("月")
plt.ylabel("売上(万円)")
plt.xticks(months)
plt.legend(title="店舗")
plt.grid(True, linestyle="--", alpha=0.4)
plt.tight_layout()
plt.show()
print("折れ線グラフを描画しました。")
折れ線グラフを描画しました。

棒グラフ(bar)の基本
月別・店舗別のグループ化棒グラフ
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
# 月(1~6月)
months = np.arange(1,
7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
mpl.rcParams["axes.unicode_minus"] = False
index = np.arange(len(months)) # x位置
width = 0.35 # 棒の幅
plt.figure(figsize=(7, 4))
plt.bar(index - width/2, sales_A, width=width, color="C0", label="A店")
plt.bar(index + width/2, sales_B, width=width, color="C1", label="B店")
# 軸とタイトル
plt.title("月別売上(棒グラフ)")
plt.xlabel("月")
plt.ylabel("売上(万円)")
plt.xticks(index, months)
# 棒の上に値を注記
for i, v in enumerate(sales_A):
plt.text(i - width/2, v + 1, f"{v}", ha="center", va="bottom", fontsize=9)
for i, v in enumerate(sales_B):
plt.text(i + width/2, v + 1, f"{v}", ha="center", va="bottom", fontsize=9)
plt.legend(title="店舗")
plt.tight_layout()
plt.show()
print("棒グラフを描画しました。")
棒グラフを描画しました。

散布図(scatter)の基本
カテゴリで色分けし、透過で重なりを見やすくする
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
import numpy as np
import pandas as pd
mpl.rcParams["axes.unicode_minus"] = False
# 月(1~6月)
months = np.arange(1, 7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
# 地域カテゴリ(散布図の色分けに使う)
regions = np.array(["東", "西", "南", "北", "東", "西"])
# 月ごとに軽いノイズを入れた座標(散布図)
rng = np.random.default_rng(42)
x_scatter = months + rng.normal(0, 0.15, size=months.size)
y_scatter = sales_A * 0.8 + rng.normal(0, 5, size=months.size)
# DataFrameにまとめ
df = pd.DataFrame({
"month": months,
"sales_A": sales_A,
"sales_B": sales_B,
"region": regions,
"x_scatter": x_scatter,
"y_scatter": y_scatter
})
# regionごとに色を割り当て
region_to_color = {"東": "C0", "西": "C1", "南": "C2", "北": "C3"}
plt.figure(figsize=(6, 4))
for r in sorted(set(regions)):
mask = (df["region"] == r)
plt.scatter(df.loc[mask, "x_scatter"],
df.loc[mask, "y_scatter"],
s=60, alpha=0.8, label=f"地域:{r}",
color=region_to_color.get(r, "C7"),
edgecolor="white", linewidth=0.7)
plt.title("散布図の基本例")
plt.xlabel("説明変数X")
plt.ylabel("目的変数Y")
plt.grid(True, linestyle=":", alpha=0.5)
plt.legend()
plt.tight_layout()
plt.show()
print("散布図を描画しました。")
散布図を描画しました。

タイトル・軸ラベル・凡例の設定
読みやすいグラフは「何を示すか」が一目で分かります。
タイトル、軸ラベル、凡例を適切に設定しましょう。
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False
plt.figure(figsize=(6, 4))
plt.plot(months, sales_A, marker="o", color="C0", label="A店")
plt.title("月別売上の推移(見出しを明確に)")
plt.xlabel("月(月初基準)")
plt.ylabel("売上(万円, 税抜)")
plt.legend(title="店舗", loc="upper left", bbox_to_anchor=(1.02, 1.0)) # グラフ外に凡例
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print("タイトル・軸ラベル・凡例の設定例を描画しました。")
タイトル・軸ラベル・凡例の設定例を描画しました。
グリッド・色・マーカーの指定
好みや用途に応じて線種や点の形状を変えると、複数系列も区別しやすくなります。
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
import numpy as np
mpl.rcParams["axes.unicode_minus"] = False
# 月(1~6月)
months = np.arange(1, 7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
plt.figure(figsize=(6, 4))
plt.plot(months, sales_A, marker="o", color="C0", label="A店")
plt.title("月別売上の推移(見出しを明確に)")
plt.xlabel("月(月初基準)")
plt.ylabel("売上(万円, 税抜)")
plt.legend(title="店舗", loc="upper left", bbox_to_anchor=(1.02, 1.0)) # グラフ外に凡例
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print("タイトル・軸ラベル・凡例の設定例を描画しました。")
色・線種・マーカーを指定した例を描画しました。

よく使う主な指定(抜粋)
下表はMatplotlibの折れ線や散布図でよく使う引数の要約です。
種別 | 引数 | 例 | 説明 |
---|---|---|---|
色 | color | “C0”, “#1f77b4” | 既定の色循環やHEX指定 |
線種 | linestyle | “-“, “–“, “:” | 実線や破線 |
マーカー | marker | “o”, “s”, “^” | 点の形状 |
透過 | alpha | 0.3〜1.0 | 重なりを見やすく |
サイズ | markersize, s | 6, 60 | 折れ線はmarkersize、散布はs |
画像として保存
レポート提出や共有には画像保存が必須です。
plt.savefig
で高解像度PNG等に書き出します。
import os
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
import numpy as np
mpl.rcParams["axes.unicode_minus"] = False
# 月(1~6月)
months = np.arange(1, 7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
plt.figure(figsize=(6, 4))
plt.plot(months, sales_A, marker="o", label="A店")
plt.title("保存用のグラフ")
plt.xlabel("月")
plt.ylabel("売上(万円)")
plt.legend()
plt.tight_layout()
out_path = "sales_line.png"
plt.savefig(out_path, dpi=150, bbox_inches="tight") # dpiで解像度指定
plt.close()
print("保存しました:", os.path.abspath(out_path))
保存しました: /your/project/path/sales_line.png

Seabornで見やすく可視化
SeabornはMatplotlibの上に構築された高水準ライブラリで、少ないコードで統計的に見やすい図を描けます。
DataFrameを直接渡すだけで、カテゴリで色分けや集計を簡単に行えます。
テーマ(style)と色の設定
import seaborn as sns
import japanize_matplotlib
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False
# テーマ設定
sns.set_theme(style="whitegrid", context="notebook") # contextでフォントサイズ等を一括調整
# カラーパレットの確認・変更
palette = sns.color_palette("Set2", n_colors=8)
print("使用パレット:", palette.as_hex())
使用パレット: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3']
折れ線(lineplot)の描き方
import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
import numpy as np
import pandas as pd
mpl.rcParams["axes.unicode_minus"] = False
# 月(1~6月)
months = np.arange(1, 7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
# 地域カテゴリ(散布図の色分けに使う)
regions = np.array(["東", "西", "南", "北", "東", "西"])
# 月ごとに軽いノイズを入れた座標(散布図)
rng = np.random.default_rng(42)
x_scatter = months + rng.normal(0, 0.15, size=months.size)
y_scatter = sales_A * 0.8 + rng.normal(0, 5, size=months.size)
# DataFrameにまとめ
df = pd.DataFrame({
"month": months,
"sales_A": sales_A,
"sales_B": sales_B,
"region": regions,
"x_scatter": x_scatter,
"y_scatter": y_scatter
})
# Seaborn向けに縦長形式へ(折れ線や棒の色分けに便利)
df_long = df.melt(id_vars=["month", "region"],
value_vars=["sales_A", "sales_B"],
var_name="store",
value_name="sales")
plt.figure(figsize=(6, 4))
sns.lineplot(data=df_long, x="month", y="sales", hue="store", marker="o")
plt.title("Seabornの折れ線(lineplot)")
plt.xlabel("月")
plt.ylabel("売上(万円)")
plt.tight_layout()
plt.show()
print("Seabornのlineplotを描画しました。")
Seabornのlineplotを描画しました。

棒グラフ(barplot)の描き方
平均や合計など集計の可視化に便利です。
Seaborn 0.12以降はerrorbar
引数で誤差表示を制御します。
import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
import numpy as np
import pandas as pd
mpl.rcParams["axes.unicode_minus"] = False
# 月(1~6月)
months = np.arange(1, 7)
# 店舗A/Bの売上(例)
sales_A = np.array([50, 65, 80, 60, 75, 90])
sales_B = np.array([40, 55, 60, 70, 65, 85])
# 地域カテゴリ(散布図の色分けに使う)
regions = np.array(["東", "西", "南", "北", "東", "西"])
# 月ごとに軽いノイズを入れた座標(散布図)
rng = np.random.default_rng(42)
x_scatter = months + rng.normal(0, 0.15, size=months.size)
y_scatter = sales_A * 0.8 + rng.normal(0, 5, size=months.size)
# DataFrameにまとめ
df = pd.DataFrame({
"month": months,
"sales_A": sales_A,
"sales_B": sales_B,
"region": regions,
"x_scatter": x_scatter,
"y_scatter": y_scatter
})
# Seaborn向けに縦長形式へ(折れ線や棒の色分けに便利)
df_long = df.melt(id_vars=["month", "region"],
value_vars=["sales_A", "sales_B"],
var_name="store",
value_name="sales")
plt.figure(figsize=(7, 4))
# 店舗×月の売上をそのまま棒で(誤差線なし)
sns.barplot(data=df_long, x="month", y="sales", hue="store", errorbar=None, palette="Set2")
plt.title("Seabornの棒グラフ(barplot)")
plt.xlabel("月")
plt.ylabel("売上(万円)")
plt.tight_layout()
plt.show()
print("Seabornのbarplotを描画しました。")
Seabornのbarplotを描画しました。

散布図(scatterplot)の描き方
Seabornではhue
やsize
で、カテゴリや量的変数を直感的に表現できます。
import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False
plt.figure(figsize=(6, 4))
sns.scatterplot(data=df, x="x_scatter", y="y_scatter",
hue="region", palette="tab10", s=70, alpha=0.85, edgecolor="white", linewidth=0.7)
plt.title("Seabornの散布図(scatterplot)")
plt.xlabel("説明変数X")
plt.ylabel("目的変数Y")
plt.tight_layout()
plt.show()
print("Seabornのscatterplotを描画しました。")
Seabornのscatterplotを描画しました。

DataFrameとの相性と簡単な使い方
Seabornは列名をそのままx
やy
、hue
に渡すだけで動きます。
以下は月別合計売上を作って棒グラフにする例です。
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False
# 月ごとの総売上(万円)
df_total = df.assign(total=lambda d: d["sales_A"] + d["sales_B"])[["month", "total"]]
plt.figure(figsize=(5, 3.5))
sns.barplot(data=df_total, x="month", y="total", color="C0") # hue無しなら単色棒
plt.title("月別総売上(Seaborn + DataFrame)")
plt.xlabel("月")
plt.ylabel("総売上(万円)")
plt.tight_layout()
plt.show()
print("DataFrameとSeabornの連携例を描画しました。")
DataFrameとSeabornの連携例を描画しました。

よくあるつまずきと対処法
日本語フォントが出ない時のチェック
日本語が□(豆腐)になる場合、次の順に確認します。
記事のコードでは常にimport japanize_matplotlib
を入れています。
- コードの先頭で
import japanize_matplotlib
を実行しているか - 一度キャッシュを削除する(パスは
matplotlib.get_cachedir()
で確認) mpl.rcParams["font.family"]
の中身を確認し、IPAex系が有効かをチェック- Seabornの
set_theme
を使用した場合、その後に日本語対応フォントを再設定しているか
import matplotlib as mpl
import matplotlib
print("font.family:", mpl.rcParams.get("font.family"))
print("cache_dir :", matplotlib.get_cachedir())
mpl.rcParams['font.family'] = 'IPAexGothic' # 日本語対応フォント
print("font.family:", mpl.rcParams.get("font.family"))
font.family: ['sans-serif']
cache_dir : C:\Users\User\.matplotlib
font.family: ['IPAexGothic']
文字化けとマイナス記号の表示対策
マイナス記号は特に文字化けしやすいため、保険として以下を毎回設定します。
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False
print("axes.unicode_minus:", mpl.rcParams["axes.unicode_minus"])
axes.unicode_minus: False
Notebookでグラフが表示されない時
Jupyter環境ではplt.show()
が無くても表示されることがありますが、表示されない場合は必ずplt.show()
を明示しましょう。
古いNotebook設定なら、先頭セルで%matplotlib inline
を使うと安定します。
# Jupyterの先頭セルで
# %matplotlib inline
print("Notebookで表示が不安定な場合は、%matplotlib inline と plt.show() を併用します。")
Notebookで表示が不安定な場合は、%matplotlib inline と plt.show() を併用します。
点が重なる時のコツ
散布図で点が重なって見えないときは、以下の工夫が有効です。
どれか一つでも効果はあります。
- 透過度
alpha
を下げる(例: 0.3〜0.6) - 点のサイズ
s
を小さくする・境界線を付ける - 微小な乱数でジッターを与える
- Seabornの
hue
やstyle
で系列を分ける
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib as mpl
mpl.rcParams["axes.unicode_minus"] = False
# サンプルデータを作成
np.random.seed(0)
df = pd.DataFrame({
"x_scatter": np.random.randint(1, 5, size=100), # 離散的なカテゴリっぽいX
"y_scatter": np.random.normal(10, 3, size=100) # 正規分布に従うY
})
# xに微小ノイズを入れて重なりを回避(ジッター)
x_jitter = df["x_scatter"] + np.random.normal(0, 0.05, size=len(df))
plt.figure(figsize=(6, 4))
plt.scatter(x_jitter, df["y_scatter"], s=40, alpha=0.5, edgecolor="white", linewidth=0.6)
plt.title("点の重なりを避ける(ジッター+透過)")
plt.xlabel("X(ジッターあり)")
plt.ylabel("Y")
plt.tight_layout()
plt.show()
print("重なり対策としてジッターと透過を適用しました。")
重なり対策としてジッターと透過を適用しました。

MatplotlibとSeabornの使い分けの目安
どちらも重要ですが、目的で使い分けると効率的です。
- カスタマイズ性重視や細かな描画制御:
Matplotlib
- 少ないコードで整った図、統計的可視化やDataFrame直渡し:
Seaborn
以下に簡単な比較を示します。
観点 | Matplotlib | Seaborn |
---|---|---|
学習コスト | 中 | 低〜中 |
コード量 | やや多い | 少なめ |
デフォルトの見た目 | 素朴 | 整っている |
細かい制御 | 非常に得意 | 可能だがMatplotlib併用が前提 |
DataFrameとの相性 | 普通 | とても良い |
統計的機能(平均・信頼区間) | 自前実装 | 標準でサポート |
実務ではSeabornで素早く概観→必要になったらMatplotlibで細部を追い込む、という流れが多いです。
まとめ
本記事では、Python初心者の方がすぐに使えるように、MatplotlibとSeabornで折れ線・棒・散布図を描く基本を、日本語表示の対策やplt.savefig
による画像保存まで含めて解説しました。
japanize_matplotlibの読み込みとaxes.unicode_minus=False
の設定を習慣化すれば、文字化けとマイナス記号の問題はほぼ回避できます。
SeabornはDataFrameをそのまま渡すだけで整った図が出せるため、探索的分析に最適です。
一方で、細かな調整や高度なカスタマイズにはMatplotlibが強力です。
まずはサンプルを写経し、「データ → 図形 → 装飾 → 保存」の流れを体に覚えさせるところから始めてみてください。
可視化が自在にできるようになると、データ理解と意思決定のスピードが一段と上がります。