可視化(part 1)#

Pythonでは、最も広く利用されているmatplotlibをはじめ、Seabornplotlyなど可視化のための様々なライブラリが用意されています。

matplotlib#

matplotlibは、Pythonにおけるデータ可視化の定番ライブラリであり、幅広い種類のグラフを作成することができます。また、細かいカスタマイズが可能で、高度な可視化表現にも対応できます。 実に、matplotlibSeabornplotlyなど、多くの可視化ライブラリの基盤にもなっていまあすので、これらのラッパーを使用した場合でも、最終的な出力を調整するためには、matplotlibの構文を熟知しておく必要がしばしばあります。

import matplotlib.pyplot as plt

基本設定#

スタイルの設定#

plt.style.use命令を使用して、図のスタイルを適切に選択します。

#plt.style.use('classic')
import scienceplots
plt.style.use(['science','no-latex'])

フォントの設定#

matplotlibで図のフォントを指定することができます。特に、matplotlib をデフォルトのまま使用すると日本語のテキストは文字化けしてしまいますので、フォント設定を変更することで表示させることが必要されます。

from matplotlib import font_manager

# Path to your TTF file
ttf_path = './Noto_Sans_JP/NotoSansJP-VariableFont_wght.ttf'
# Register the font
font_manager.fontManager.addfont(ttf_path)
custom_font = font_manager.FontProperties(fname=ttf_path)

# Set the custom font as default
plt.rcParams['font.family'] = custom_font.get_name()
plt.rcParams['font.family'] = 'Hiragino Sans'
city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
plt.figure(figsize=(6,3))
plt.bar(city,population)
plt.show()
../_images/fe11bb4fb69cc6326d155d2900f7823b5ebf02672ef6f8ad4b41fe0350b83a6d.png

基本的な描画方法#

可視化を一番手軽に行うために、matplotlibではデータを渡すだけで描画してくれる関数が多数用意されています。

import numpy as np
x = np.arange(-3, 3, 0.1)
y = np.sin(x)
# 折れ線グラフ
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x135a7eb10>]
../_images/3bba8c94ded99f79f5bcd6746d9e0e98df237b34ef0c689927239b45d355ecb9.png
x = np.random.randn(30)
y = np.sin(x) + np.random.randn(30)
plt.plot(x, y, "o")  # "o"は小さい円(circle marker)
[<matplotlib.lines.Line2D at 0x135b0c290>]
../_images/03baa3ab229475aae22635107cdd145cc26007faa84963624158a0d42f4b4c0e.png
# ヒストグラム
plt.hist(np.random.randn(1000))
(array([  7.,  29.,  69., 150., 243., 251., 143.,  77.,  25.,   6.]),
 array([-3.13635169, -2.51532708, -1.89430246, -1.27327785, -0.65225323,
        -0.03122862,  0.58979599,  1.21082061,  1.83184522,  2.45286984,
         3.07389445]),
 <BarContainer object of 10 artists>)
../_images/4256c75e18830643ebaa8b428b8c5c0e0451a2a6b5ed4b2dd9826c147525f281.png
x = np.linspace(0,10,50)
dy = 0.8
y = np.sin(x)+dy*np.random.randn(50)

plt.errorbar(x,y,yerr=dy)
<ErrorbarContainer object of 3 artists>
../_images/3ea2ff84178a3fbfc3c0e991a63679a184ea5e828827bd5e7ce02006e37a1b4b.png

オブジェクト指向なプロット#

ここまではmatplotlib.pyplotモジュールの関数を利用することでグラフを描画する方法を紹介しましたが、この方法では、描画している図が暗に行われているため、細かい設定を行うことが難しいです。

そこで、より明示的な方法で描画ができるオブジェクト指向なインターフェースを使った方法を解説します。

「オブジェクト指向インターフェース」はFigureAxesなどのオブジェクトを用いてグラフを作成する方法です。

  • Figureオブジェクト

    • グラフや軸を描くための土台となるオブジェクト:サイズやレイアウトなどグラフ全体に関する設定を行い、軸、グラフィックス、テキスト、ラベルなど、全ての描画要素を含むコンテナと考えることができます。

  • Axexオブジェクト

    • AxexオブジェクトはFigureオブジェクトの子として作成され、Figure内の1つのプロットエリアを表します。これが実際にデータをプロットする領域です。

グラフ作成の主な流れ#

オブジェクト指向インターフェースにおけるグラフ作成の流れは以下の通りです。

  • plt.figure()でFigureオブジェクト(土台)を作成

  • plt.add_subplot()でAxesオブジェクトを作成

  • Axes.plot()などのメソッドでグラフを作成

  • Axes.set_title()などのメソッドでグラフのスタイルを調整

  • plt.show()でグラフを表示

# プロットに対して、図(figure)と座標軸(axex)の作成を最初に行います。
fig = plt.figure()
ax = fig.add_subplot()

#プロットするデータ
x = np.linspace(-5, 5, 100)
y = np.sin(x)

#プロット
ax.plot(x, y)

#グラフのスタイルの微調整を行います。
ax.set_title('y=sin(x)')
ax.set_xlabel('x')
ax.set_ylabel('y')

plt.show()
../_images/d086a4f606b5af0e9c5d4729c7766cab5d5f771e21e1c17bc9c2754b9f02d678.png

同じAxesオブジェクトからグラフを作成するメソッドを複数回呼び出すと、1つのAxesに複数のグラフを重ねて描くことができます。

x = np.linspace(-5, 5, 100)
y = np.sin(x)

fig = plt.figure()
ax = fig.add_subplot()

#2つのグラフを同じAxesに作成
ax.plot(x, y)
ax.plot(x, 2*y, '--')

plt.show()
../_images/68dc46fa15d4989399dae1f99afd3d3be61417b9bc7cd25925d96997bea6e270.png

複数サブプロット#

サブプロットの単純なグリッド#

列または行で整列したサブプロットの集合で結果を可視化することは非常に一般です。

オブジェクト指向インターフェースでは、こうした複数のプロットを一つの図にまとめる場合には特に有用です。

# Figureオブジェクトを作成
fig = plt.figure(figsize=(6, 3))

# FigureにAxesを追加
ax1 = fig.add_subplot(1, 2, 1)  # 1行2列の最初のサブプロット
ax2 = fig.add_subplot(1, 2, 2)  # 1行2列の2番目のサブプロット

# 各Axesにプロットを追加
x = np.linspace(-5, 5, 100)
ax1.plot(x, np.sin(x))
ax2.plot(x, np.cos(x))

# 図を表示
plt.show()
../_images/0aa2cc4645fde267bda6cbe4c72953cf517233f421766999b1dedf54653a1deb.png

plt.subplotsで、単一のサブプロットを作成するのではなく、一回の呼び出しでサブプロットのグリッドを作成することができます。これにより、複数のプロットを一つの図内で並べて表示することが簡単にできます。

# 2x2のサブプロットグリッドを作成
fig, axs = plt.subplots(2, 2, sharex="col", sharey="row")

# 各サブプロットにデータをプロット
axs[0, 0].plot([1, 2, 3, 4], [10, 20, 25, 30])
axs[0, 0].set_title('Plot 1')

axs[0, 1].plot([1, 2, 3, 4], [30, 25, 20, 15])
axs[0, 1].set_title('Plot 2')

axs[1, 0].plot([1, 2, 3, 4], [15, 18, 22, 26])
axs[1, 0].set_title('Plot 3')

axs[1, 1].plot([1, 2, 3, 4], [5, 15, 20, 25])
axs[1, 1].set_title('Plot 4')

# レイアウトを調整
plt.tight_layout()

# グラフを表示
plt.show()
../_images/be3c23669509912c231e2976d4f483b5c23744db293ce3304d33b3b478f97a24.png

プロットの作成#

matplotlibでは、さまざまなカスタマイズや設定を行うことができます。

線グラフ#

線の主な書式を以下の表に示します。

引数

説明

linewidth/lw

線の太さ

color/c

線の色

alpha

色の透明度

linestyle

線の種類

色の変更は、colorキーワードに色を表す文字列引数を指定します。色の指定方法には様々な方法があります。

x = np.linspace(0, 10, 1000)
fig = plt.figure()
ax = fig.add_subplot()
ax.plot(x, np.sin(x - 0), color='blue')        # specify color by name
ax.plot(x, np.sin(x - 1), color='g')           # short color code (rgbcmyk)
ax.plot(x, np.sin(x - 2), color='0.75')        # grayscale between 0 and 1
ax.plot(x, np.sin(x - 3), color='#FFDD44')     # hex code (RRGGBB, 00 to FF)
ax.plot(x, np.sin(x - 4), color=(1.0,0.2,0.3)) # RGB tuple, values 0 to 1
ax.plot(x, np.sin(x - 5), color='chartreuse'); # HTML color names supported
../_images/c435d209ae0880befbbae153786f3f3fe9ba1f86974fc5c7efd64b8b69afe5c4.png

同様に、linesyleキーワードを使用して線のスタイルを調整することもできます。

fig = plt.figure()
ax = fig.add_subplot()
ax.plot(x, x + 0, linestyle='solid')
ax.plot(x, x + 1, linestyle='dashed')
ax.plot(x, x + 2, linestyle='dashdot')
ax.plot(x, x + 3, linestyle='dotted');

# For short, you can use the following codes:
ax.plot(x, x + 4, linestyle='-')  # solid
ax.plot(x, x + 5, linestyle='--') # dashed
ax.plot(x, x + 6, linestyle='-.') # dashdot
ax.plot(x, x + 7, linestyle=':');  # dotted
../_images/c15b2cbc232f06407009196b2baf0fb9553e96252faa635577290d14d67b4bc6.png

また、線スタイルとカラーコードでまとめて指定することもできます。

fig = plt.figure()
ax = fig.add_subplot()
ax.plot(x, x + 0, '-g')   # solid green
ax.plot(x, x + 1, '--c')  # dashed cyan
ax.plot(x, x + 2, '-.k')  # dashdot black
ax.plot(x, x + 3, ':r');  # dotted red
../_images/3355c7539cc7fe4daf66c80a3622c8601b2632277237614accf634f1d56c9e0b.png

線の色とスタイルに加えて、データポイントにマーカーを追加することもできます。marker引数を使用します。

fig, ax = plt.subplots()

# 線の色、スタイル、マーカーを指定
ax.plot([1, 2, 3, 4], [10, 30, 50, 70], color='red', linestyle='-', marker='o')
ax.plot([1, 2, 3, 4], [20, 40, 60, 80], color='blue', linestyle='--', marker='x')

ax.legend()
plt.show()
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
../_images/b463b3424ab1a5bf70110ec455e9b152772c192437489ea9e5d00a1771aa9e6d.png

棒グラフ#

棒の色を指定するには、同様にcolor引数を使用します。

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population,color='skyblue')
<BarContainer object of 10 artists>
../_images/1d8b8a22f4c067867bc165eb7c4ab91e5e00d2b7c0d6700c280e7dda20a4b6ef.png

棒の幅を指定するには、width引数を使用します。

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population,color='skyblue', width=0.5)
<BarContainer object of 10 artists>
../_images/fa1685c50ac7f8118ed216ef452b3dda642828ced1f9034b5a490b3818b2f205.png

棒に枠線を付ける場合、枠線の色をedgecolor, 枠線の太さをlinewidthで指定します。

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population,color='skyblue', width=0.5,edgecolor="black", linewidth=0.5)
<BarContainer object of 10 artists>
../_images/2b2f127204052cb97b624199870121e76e23e17eda5d821eb4b149016f2b8064.png

横棒グラフを出力するには、ax.barhを使用します。ax.barhの最初の引数が縦軸方向の位置、2番目の引数が棒の長さとなります。

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.barh(city, population,color='skyblue',edgecolor="black", linewidth=0.5)
<BarContainer object of 10 artists>
../_images/bacd13af11f849397768c27a84adabff56d3baec4e7648be8095b93a6ada1037.png

棒の位置を調整するために、棒の中心をシフトすることができます。

categories = ['A', 'B', 'C', 'D']
x = np.arange(len(categories))
values1 = [10, 24, 36, 40]
values2 = [20, 18, 30, 35]

width = 0.4  # 幅を設定

fig, ax = plt.subplots(figsize=(6, 3))

# 2つのデータセットを並べて表示
ax.bar(x - width/2, values1, width=width, color='blue')
ax.bar(x + width/2, values2, width=width, color='orange')

ax.set_xticks(x)
ax.set_xticklabels(categories)
[Text(0, 0, 'A'), Text(1, 0, 'B'), Text(2, 0, 'C'), Text(3, 0, 'D')]
../_images/a78aecf5975c527e49bf7bf61556aa283b19605707be65a45993a2cb3f840050.png

積み上げ棒グラフを作成する場合、bottomオプションで下になるデータを指定します。

x = np.array([1, 2, 3, 4, 5]) # 横軸の値
y1 = np.array([5, 3, 7, 4, 5]) # 下側のデータ
y2 = np.array([3, 6, 2, 1, 1]) # 上側のデータ

fig, ax = plt.subplots()
ax.bar(x, y1, label="y1")
ax.bar(x, y2, label="y2", bottom=y1)
ax.legend()
plt.show()
../_images/9cb561fe59625f4ffe06fec30aa07a994518e2ef95cb92854252ae6dddeff46c.png

ヒストグラム#

ヒストグラムを出力するには、ax.histを使用します。ax.histの最初の引数に表示するデータを配列で与えます。

np.random.seed(seed=0)
x = np.random.normal(10, 5, 100) # 平均10, 標準偏差5の正規分布で100点のデータを生成

fig, ax = plt.subplots()
ax.hist(x)
plt.show()
../_images/0181b7c52031623678d0b27c25dfd09cbd2bb2aafce8aedc54d4dd0ceaefcbba.png

表示する棒の数はbinsオプションで指定できます(デフォルトは10)。

fig, ax = plt.subplots()
ax.hist(x, bins=20)
plt.show()
../_images/22549ea4ef6399ee619342d8cfab56fe06adf9e215eab649cbb7cc73b1bf92a2.png
  • 棒の太さはrwidthオプションで指定できます。0から1の範囲を取り、値が小さいほど細くなります。

  • 棒の色はcolorオプションで指定できます。colorオプションの詳細は以下の記事を参考にして下さい。

  • alphaオプションで透明度を変更できます。0から1の範囲を取り、値が小さいほど透明に近づきます。

fig, ax = plt.subplots()
ax.hist(x, bins=20, rwidth=0.8, color="green", alpha=0.5)
plt.show()
../_images/f7432e53eabbd0f089016c7140922651a19ff9c2136d3087620f7ebc445e3893.png

複数系列のデータからヒストグラムを作成するする方法を示します。

まず、単純に棒を横に並べる例です。ax.histに複数のデータをリストで渡します。

np.random.seed(seed=0)
x1 = np.random.normal(10, 5, 100) # 平均10, 標準偏差5の正規分布で100点のデータを生成
x2 = np.random.normal(20, 10, 100) # 平均20, 標準偏差10の正規分布で100点のデータを生成

fig, ax = plt.subplots()
ax.hist([x1, x2])
ax.legend(["x1", "x2"])
plt.show()
../_images/1deb74ccdf43d50b60bbc586b75d7b0f941fa2f09f09f4905c9dec3611f05012.png

alphaオプションを使って棒を透過させ、重ねて表示することも可能です。

fig, ax = plt.subplots()
ax.hist(x1, alpha=0.5, label="x1")
ax.hist(x2, alpha=0.5, label="x2")
ax.legend()
plt.show()
../_images/9b46752256ee5e42156c4fffe440f6bc8f38f5c12be424a574fae192bc03e074.png

ヒストグラムを積み上げる場合、histtype="barstacked"とするか、stacked=Trueとします。

fig, ax = plt.subplots()
ax.hist([x1, x2], histtype="barstacked")
# ax.hist([x1, x2], stacked=True) # これも同じ結果になる
ax.legend(["x1", "x2"])
plt.show()
../_images/12f73102392f9c59f032c6f9d4e059a67a56cbc1e5d904ce313c05249d84fe4b.png

箱ひげ図#

箱ひげ図をプロットするには、ax.boxplotを使用します。ax.boxplotに渡すデータ(以下の例ではx)が1次元配列の場合、箱ひげ図は1個だけ出力されます。一方、データが2次元配列の場合、箱ひげ図は列の数だけ出力されます。

np.random.seed(seed=0)
x = np.random.normal(10, 5, 1000).reshape(-1,2)
# 平均10, 標準偏差5の正規分布。500行2列の配列データを生成

fig, ax = plt.subplots()
ax.boxplot(x)
plt.show()
../_images/dfb4ffdadb6e7404751256031baaba6c9b2a2093a52d0dc4736c73fd2382b9c4.png

boxplotで指定できる主なオプションを以下に示します。

  • sym (str): 外れ値記号の見た目

  • flierprops (dict): 外れ値記号の見た目

  • vert (bool): Trueの場合、箱ひげ図は横向きになる(デフォルト:False

  • whis (float/(float, float)): ひげの開始位置(デフォルト:1.5

  • widths (float): 箱の幅

  • labels (sequence): データのラベル(横軸に表示)

  • showmeans (bool): Trueの場合、平均値を表示する(デフォルト:False

widthsオプションで箱の幅を指定できます(デフォルトは0.5、またはグラフの幅から自動的に決定されます)。

fig, ax = plt.subplots()
ax.boxplot(x, widths=0.3)
plt.show()
../_images/3e10381beedca948f04df1bd767d531130a373d1ef22d7c865d69ada8eb4eb5f.png

labelsオプションでデータのラベルを指定できます。

fig, ax = plt.subplots()
ax.boxplot(x, labels=["A", "B"])
plt.show()
../_images/a0f293111d42bf41e4e485888190900e9d5525f5c44803280fbabf9097a5e20e.png

平均値を表示するにはshowmeans=Trueとします。平均値マーカーの表示方法は、meanpropsオプションに辞書形式で指定できます。

fig, ax = plt.subplots(1,2,figsize=(6,3))
ax[0].boxplot(x, showmeans=True)
ax[1].boxplot(x, showmeans=True, meanprops={"marker":"x", "markeredgecolor":"blue", "ms":10})
plt.show()
../_images/55b02901b2f021e476344c190cb48b1d97662e43ef237ae2a40cad98b94bcce2.png

散布図#

散布図を出力するには、ax.scatterを使用します。ax.scatterの最初の引数に横軸方向の値、2番目の引数に縦軸方向の値をそれぞれ配列で与えます。

import numpy as np

x = np.array([4, 6, 7, 3, 5]) # 横軸の値
y = np.array([5, 3, 7, 4, 6]) # 縦軸の値

fig, ax = plt.subplots()
ax.scatter(x, y)
plt.show()
../_images/3be7883e53dcce017c3a425cf2424b47606e0d4755709dd8c95d7260ee96e70a.png

散布図に系列を追加したい場合、以下のようにax.plotを追加します。labelオプションとax.legend()を使うことで、系列名を凡例として表示できます。

x2 = np.array([1, 3, 2, 5, 6]) # 横軸の値
y2 = np.array([2, 5, 4, 7, 6]) # 縦軸の値

fig, ax = plt.subplots()
ax.scatter(x, y, label="y")
ax.scatter(x2, y2, label="y2")
ax.legend()
plt.show()
../_images/b70a4d67f907531563aec5666ec6ec396ddedab33406259ba5f078b9da7aba20.png

マーカーの大きさ・色・種類を変更することができます

  • マーカーの大きさはsオプションで指定します。

  • マーカーの色はcオプションで指定します。

  • alphaオプションで透明度を変更できます。0から1の範囲を取り、値が小さいほど透明に近づきます。

  • マーカーの種類はmarkerオプションで指定します。

x2 = np.array([1, 3, 2, 5, 6]) # 横軸の値
y2 = np.array([2, 5, 4, 7, 6]) # 縦軸の値

fig, ax = plt.subplots()
ax.scatter(x, y, label="y", c="lightblue",s=35,marker="+")
ax.scatter(x2, y2, label="y2",c="black",s=20,alpha=0.8,marker="s")
ax.legend()
plt.show()
../_images/4f7e81867d46df1a02f0f6cfb2a805e400538161cc89bc2c8e361bd4e091a353.png

散布図の各点の色を、値に合わせて指定できます。cに値を、cmapにカラーマップを指定します。

指定可能なカラーマップについては、以下のページも参照下さい。

Matplotlibのカラーマップ

カラーバーを表示する場合、plt.colorbarを使用します。ax.scatterの戻り値はPathCollectionというクラスのオブジェクトです。これをplt.colorbarの最初の引数とします。また、axオプションにカラーバーを表示するグラフ(ここではax)を指定します。

x1 = np.array([1, 2, 3, 4]) # 横軸の値
y1 = np.array([1, 2, 3, 4]) # 縦軸の値
v1 = np.array([1, 2, 3, 4]) # 点の色に対応する値

fig, ax = plt.subplots()
ax.scatter(x1, y1, c=v1, cmap="Reds")
plt.show()
../_images/1586cac86a24d6b7355f4d7dabe21796f7ca39638bf04b0a0566f02626cb4cdd.png

また、表示するカラーマップの範囲を固定したい場合、最小値と最大値をそれぞれvmin, vmaxで指定します。

fig, ax = plt.subplots()
mappable = ax.scatter(x1, y1, c=v1, cmap="Reds", vmin=-5, vmax=3)
plt.colorbar(mappable, ax=ax)
plt.show()
../_images/bfd8f1f4c4cc62167fcbca297e71337647d756fb75a90096bf215efcb1ff80d1.png

プロットの制御#

タイトル・軸ラベルの表示#

グラフタイトル、x軸のラベル、y軸のラベルを表示と調整することができます。

  • fontsize: タイトル(軸ラベル)のフォントサイズを指定します。

  • loc: タイトルの位置を指定します。‘left’, ‘center’, ‘right’のいずれかを選択できます。

  • pad: タイトルとプロットの間のパディングを指定します。

  • labelpad: 軸ラベルと軸の間のパディングを指定します。

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population,color='skyblue', width=0.8)
ax.set_title("日本における各都市の人口規模",fontsize=16, loc='center',pad=20)
ax.set_xlabel('都市名', fontsize=14,labelpad=10)
ax.set_ylabel('人口数', fontsize=14,labelpad=10)
Text(0, 0.5, '人口数')
../_images/018cb15332d8453a9b301a8fd7f30e731ca733d54efe3b8afe517aec2de13147.png

軸の目盛#

x軸とy軸には、プロットする値に応じて自動的に目盛ラベルが表示されますが、さらにカスタマイズすることもできます。

  • x軸

    • set_xticksメソッドでx軸の目盛り位置を設定します。range(len(city))は都市の数に基づいて目盛り位置を設定しています。

    • set_xticklabelsメソッドで目盛りラベルを設定し、45度回転させています。

  • y軸

    • set_yticksメソッドでy軸の目盛り位置を設定します

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population,color='skyblue', width=0.8)
ax.set_title("日本における各都市の人口規模",fontsize=16, loc='center',pad=20)
ax.set_xlabel('都市名', fontsize=14,labelpad=10)
ax.set_ylabel('人口数', fontsize=14,labelpad=10)
# x軸の目盛りラベルを設定
ax.set_xticks(range(len(city)))
ax.set_xticklabels(['東京都', '横浜市', '大阪府', '名古屋市', '札幌市', '神戸市', '京都府', '福岡市', '広島市', '仙台市'], rotation=45)
# y軸の目盛りを調整
ax.set_yticks([0, 5000000, 10000000, 15000000])
[<matplotlib.axis.YTick at 0x13760d700>,
 <matplotlib.axis.YTick at 0x1377b11f0>,
 <matplotlib.axis.YTick at 0x13760d400>,
 <matplotlib.axis.YTick at 0x137760aa0>]
../_images/e200fa69cb44dd62fb21b4df617931e39b41492ab260ebfeb1766ece58d7e05c.png

目盛りのさらに詳細な設定をするには、Axes.tick_params()メソッドを用います。このメソッドの主なオプションを以下に示します。

オプション

説明

axis

str

軸を選択(‘both’, ‘x’, ‘y’)

which

str

目盛り線の種類を指定。‘major’(主目盛り)、‘minor’(補助目盛り)、‘both’(両方の目盛り)

direction

str

目盛りの位置。‘in’, ‘out’, ‘inout’

length

float

目盛りの長さ

width

float

目盛りの幅

color

str

目盛りの色

pad

float

目盛りと目盛りラベルの隙間

labelsize

float

目盛りラベルの大きさ

labelcolor

str

目盛りラベルの色

colors

str

目盛りと目盛りラベルの色

zorder

float

描画する順序

labelrotation

float

目盛りラベルの回転角度(半時計回りに回転。単位は度)

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population,color='skyblue', width=0.8)
ax.set_title("日本における各都市の人口規模",fontsize=16, loc='center',pad=20)
ax.set_xlabel('都市名', fontsize=14,labelpad=10)
ax.set_ylabel('人口数', fontsize=14,labelpad=10)
# x軸の目盛りラベルを設定
ax.set_xticks(range(len(city)))
ax.set_xticklabels(['東京都', '横浜市', '大阪府', '名古屋市', '札幌市', '神戸市', '京都府', '福岡市', '広島市', '仙台市'], rotation=45)
# y軸の目盛りを調整
ax.set_yticks([0, 5000000, 10000000, 15000000])
ax.tick_params(labelcolor="red", width=5, direction='inout')
../_images/4f62d4ab1777371fb2cedc2b6d2f01f4019426b6460edc9f91c88d73da474960.png

目盛り線を引くには、Axes.grid()メソッドを用います。

  • axis: 軸を選択(‘both’, ‘x’, ‘y’)

  • which: 目盛り線の種類を指定。‘major’(主目盛り)、‘minor’(補助目盛り)、‘both’(両方の目盛り)

  • linewidth

  • color

  • linestyle

city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population,color='skyblue', width=0.8)
ax.set_title("日本における各都市の人口規模",fontsize=16, loc='center',pad=20)
ax.set_xlabel('都市名', fontsize=14,labelpad=10)
ax.set_ylabel('人口数', fontsize=14,labelpad=10)
# x軸の目盛りラベルを設定
ax.set_xticks(range(len(city)))
ax.set_xticklabels(['東京都', '横浜市', '大阪府', '名古屋市', '札幌市', '神戸市', '京都府', '福岡市', '広島市', '仙台市'], rotation=45)
# y軸の目盛りを調整
ax.set_yticks([0, 5000000, 10000000, 15000000])
#目盛り線を引く
ax.grid(axis="y")
../_images/14937d939102e53e0528058496587d2840ea2a552d3d900d4e6aaa9199871513.png

グラフに文字をつける#

グラフにテキストやマークをつけることで、関連する追加情報を提供することができます。

文字をつけるには、ax.textメソッドを使用します。このメソッドには、注釈をつけるテキスト、位置、およびその他のスタイルオプションを指定できます。

基本的には、ax.text(x, y, s)は文字列を描画することができます。ここで、xyは文字列の左下のx, y座標であり、sは表示する文字列です。

フォントに関する主な書式を以下の表に示します。

引数

説明

fontfamily/family

‘serif’, ‘sans-serif’, ‘cursive’(筆記体), ‘fantasy’(装飾の多いフォント), ‘monospace’(等幅フォント)

fontsize/size

floatの数値、または’xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’

fontstyle/style

‘normal’, ‘italic’(斜体), ‘oblique’(斜体)

fontstretch/stretch

文字の横幅。0~1000の範囲の数値、または ‘ultra-condensed’, ‘extra-condensed’, ‘condensed’, ‘semi-condensed’, ‘normal’, ‘semi-expanded’, ‘expanded’, ‘extra-expanded’, ‘ultra-expanded’

fontweight/weight

文字の太さ。0~1000の範囲の数値、または’ultralight’, ‘light’, ‘normal’, ‘regular’, ‘book’, ‘medium’, ‘roman’, ‘semibold’, ‘demibold’, ‘demi’, ‘bold’, ‘heavy’, ‘extra bold’, ‘black’

color/c

文字の色

また、文字の配置に関する主な書式を以下の表に示します。

引数

説明

horizontalalignment/ha

横方向の位置。‘left’, ‘center’, ‘right’

verticalalignment/va

縦方向の位置。‘bottom’, ‘baseline’, ‘center’, ‘center_baseline’, ‘top’

multialignment or ma

複数行の位置。‘left’, ‘right’, ‘center’

linespacing

行間の広さをフォントサイズの倍数で指定

rotation

文字の回転。角度(°)または、‘vertical’(90), ‘horizontal’(0)

フォントファミリー#

フォントファミリー(フォントの種類)はfontfamilyまたはfamilyオプションで変更できます。‘serif’, ‘sans-serif’, ‘cursive’(筆記体), ‘fantasy’(装飾の多いフォント), ‘monospace’(等幅フォント)から選択可能です。以下に例を示します。

fig, ax = plt.subplots()
ax.text(0.1, 0.9, "serif", fontfamily="serif", fontsize=20)
ax.text(0.1, 0.7, "sans-serif", fontfamily="sans-serif", fontsize=20)
ax.text(0.1, 0.5, "cursive", fontfamily="cursive", fontsize=20)
ax.text(0.1, 0.3, "fantasy", fontfamily="fantasy", fontsize=20)
ax.text(0.1, 0.1, "monospace", fontfamily="monospace", fontsize=20)
plt.show()
../_images/4a51f6e468bb9ae1588d34e379c1bfebeef6055a95e9a121576582480e6d50d0.png
文字の太さ#

文字列の太さはfontweightまたはweightオプションで変更できます。0~1000の範囲の数値で指定、または’ultralight’, ‘light’, ‘normal’, ‘regular’, ‘book’, ‘medium’, ‘roman’, ‘semibold’, ‘demibold’, ‘demi’, ‘bold’, ‘heavy’, ‘extra bold’, ‘black’から選択します。以下に例を示します。

fig, ax = plt.subplots(figsize=(6,4))
ax.text(0.1, 0.9, "fontweight (ultralight)", fontweight="ultralight", fontsize=20)
ax.text(0.1, 0.7, "fontweight (normal)", fontweight="normal", fontsize=20)
ax.text(0.1, 0.5, "fontweight (semibold)", fontweight="semibold", fontsize=20)
ax.text(0.1, 0.3, "fontweight (bold)", fontweight="bold", fontsize=20)
ax.text(0.1, 0.1, "fontweight (black)", fontweight="black", fontsize=20)
plt.show()
../_images/fb7e8e2474dc456b3d37c2b5626281681007c4f9e6eacb70c7f14a6bfb97aaed.png
横方向の位置#

テキストの横方向の位置は、horizontalalignmentまたはhaオプションに'left', 'center', 'right'のいずれかを与えて指定します。 ax.text(x, y, s)の最初の引数xで文字列の横方向の位置を指定しますが、

  • 'left': xが文字列の左端の座標になる(デフォルト)

  • 'center': xが文字列の中央の座標になる

  • 'right': xが文字列の右端の座標になる

となります。

以下にx=0.5としたときの例を示します。

fig, ax = plt.subplots()
ax.text(0.5, 0.9, "left", horizontalalignment="left", fontsize=20)
ax.text(0.5, 0.7, "center", horizontalalignment="center", fontsize=20)
ax.text(0.5, 0.5, "right", horizontalalignment="right", fontsize=20)
ax.grid()
plt.show()
../_images/3c4f25c088f1e069feb34938c60b54521d20cbb9686a51a970aef306fb192b9a.png
行間の広さ#

テキストの行間の広さはlinespacingオプションで指定します。以下にデフォルトの行間とlinespacingを1, 1.5とした例をそれぞれ示します(デフォルトの値は1.2です)。 また、"\n"は改行を意味します。

fig, ax = plt.subplots(figsize=(6,4))
ax.text(0.1, 0.2, "foo\nbar\nnspace", fontsize=20) # デフォルトの行間
ax.text(0.4, 0.2, "foo\nbar\nspace 1", linespacing=1, fontsize=20)
ax.text(0.7, 0.2, "foo\nbar\nspace 1.5", linespacing=1.5, fontsize=20)
ax.grid()
plt.show()
../_images/0b48a463f0924d00536e75ff62a0a293465f25b552800ecfcbe682d0df2761f9.png
city=['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population= [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
fig, ax = plt.subplots(figsize=(6, 3))
bars = ax.bar(city, population,color='skyblue', width=0.8)
ax.set_title("日本における各都市の人口規模",fontsize=16, loc='center',pad=20)
ax.set_xlabel('都市名', fontsize=14,labelpad=10)
ax.set_ylabel('人口数', fontsize=14,labelpad=10)
# x軸の目盛りラベルを設定
ax.set_xticks(range(len(city)))
ax.set_xticklabels(['東京都', '横浜市', '大阪府', '名古屋市', '札幌市', '神戸市', '京都府', '福岡市', '広島市', '仙台市'], rotation=45)
# y軸の目盛りを調整
ax.set_yticks([0, 5000000, 10000000, 15000000])
#目盛り線を引く
ax.grid(axis="y")

ax.text(6.5, 12000000, s="2019年時点のデータ\nになります",fontsize=10,horizontalalignment="left")
Text(6.5, 12000000, '2019年時点のデータ\nになります')
../_images/cfc4f1fd3f74a5a332221ce29aae78e1d33caf7530ff6b108f60f0ae4c0d10dd.png

凡例の設定#

プロットの凡例は、様々なプロット要素にラベルを割り当て、可視化の結果をわかりやすくします。

凡例の表示#

凡例を表示する方法はいくつかあります。

1つ目は、データをプロットする際にlabel引数でラベルを設定し、legend()メソッドで凡例を表示する方法です。

2つ目は、legend()メソッドにラベルを与える方法です。ラベルはリストで与えます。

それぞれの例を以下に示します。どちらも同じ結果となります。

# label引数でラベルを設定する
fig, ax = plt.subplots(1,2,figsize=(6,3))
ax[0].plot([1, 3, 2], label="data 1")
ax[0].plot([3, 1, 1], label="data 2")
ax[0].legend()

ax[1].plot([1, 3, 2])
ax[1].plot([3, 1, 1])
ax[1].legend(["data 1", "data 2"])
plt.show()
../_images/b74025bcb7ca331603b1571ddda70cea24dd7e8c476f45b4c0cc28c64eb2df96.png
凡例の位置#

凡例の位置はlegend()メソッドのlocオプションで指定できます。デフォルト値はbest(プロットと凡例がなるべく重ならないように配置する)です。また、以下からも指定可能です。

---------------------------------------
|upper left |upper center|upper right |
---------------------------------------
|center left|center      |center right|
---------------------------------------
|lower left |lower center|lower right |
---------------------------------------

凡例の位置を左側中段 (center left) とした例を以下に示します。

fig, ax = plt.subplots()
ax.plot([1, 3, 2], label="data 1")
ax.plot([3, 1, 1], label="data 2")
ax.legend(loc="center left")
plt.show()
../_images/11bfbb49411f4bcc509a2f1bf2109025c24a569f3e2119be22ac8a555e6b32be.png

また、凡例の位置はbbox_to_anchorオプションでも指定可能です。このオプションに座標を(x, y)で渡します。グラフの左下が(0, 0), 右上が(1, 1)となります。bbox_to_anchorにそれぞれ(0, 0)と(1, 1)を指定した例を以下に示します。

fig, ax = plt.subplots(1,2,figsize=(6,3))
ax[0].plot([1, 3, 2], label="data 1")
ax[0].plot([3, 1, 1], label="data 2")
ax[0].legend(bbox_to_anchor=(0, 0))

ax[1].plot([1, 3, 2], label="data 1")
ax[1].plot([3, 1, 1], label="data 2")
ax[1].legend(bbox_to_anchor=(1, 1))
<matplotlib.legend.Legend at 0x1687d88f0>
../_images/00760eccda3dfb233ff3a1fa73707a1d73d729294cbf6be4e41671f1f6afde89.png
凡例の列数#

凡例の列数はlegend()メソッドのncolオプションで指定できます。以下は列数を2とした例です。

fig, ax = plt.subplots()
ax.plot([1, 3, 2], label="data 1")
ax.plot([3, 1, 1], label="data 2")
ax.plot([2, 2, 1], label="data 3")
ax.legend(ncol=2)
plt.show()
../_images/31c4b750bcd4c64a1e09e162d2ef72d9f6a0277afdfda7c67320006ac7b88053.png
凡例の色#

凡例の文字色はlegend()メソッドのlabelcolor, 背景色はfacecolor, 枠線の色はedgecolorでそれぞれ指定できます。また、背景色の透過度はframealphaで指定できます(0~1の範囲で指定し、値が小さいほど透明に近づきます)。

fig, ax = plt.subplots()
ax.plot([1, 3, 2], label="data 1")
ax.plot([3, 1, 1], label="data 2")
ax.legend(labelcolor="red", facecolor="blue", edgecolor="orange", framealpha=0.2)
<matplotlib.legend.Legend at 0x1375ea450>
../_images/5b83de027088ea015f1eb9d726901ce76547d143cf26f40a0e52cec360558ca8.png
凡例の文字サイズ#

凡例の文字サイズはlegend()メソッドのfontsizeオプションで指定できます。整数または次のいずれかから指定可能です。 {"xx-small", "x-small", "small". "medium", "large", "x-large", "xx-large"}

fig, ax = plt.subplots()
ax.plot([1, 2, 2], label="data 1")
ax.plot([3, 1, 1], label="data 2")
ax.legend(fontsize=18)
<matplotlib.legend.Legend at 0x137761d60>
../_images/013ce61c81d69926c9375b83fed86151548657f79d81657e6e4665b82d430c3f.png
凡例のタイトル#

凡例にタイトルを設定する場合、legend()メソッドのtitleオプションで指定できます。以下はタイトルを”Prices”と設定した例です。

fig, ax = plt.subplots()
ax.plot([1, 2, 2], label="data 1")
ax.plot([3, 1, 1], label="data 2")
ax.legend(title="Prices")
<matplotlib.legend.Legend at 0x1683815b0>
../_images/a58d8f9b44b8e7053fc19288d4c994ffebd40139492a5ead3c726c21437cf6e3.png
# Define the data
city = ['東京', '横浜', '大阪', '名古屋', '札幌', '神戸', '京都', '福岡', '広島', '仙台']
population = [13929286, 3723392, 2691004, 2390411, 1952356, 1538316, 1474570, 1532591, 1196564, 1098330]
regions = ["関東", "関東", "関西", "中部", "東北・北海道", "関西", "関西", "九州・中国", "九州・中国", "東北・北海道"]

# Define the colors for each region
region_colors = {
    "関東": "#88CEE6",
    "関西": "#F6C8A8",
    "中部": "#B2D3A4",
    "東北・北海道": "#E6CECF",
    "九州・中国": "#80C1C4"
}

fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(city, population, color=[region_colors[region] for region in regions],label=regions,edgecolor="black", linewidth=.9)

ax.set_title("日本における各都市の人口規模", fontsize=16, loc='center', pad=20)
ax.set_xlabel('都市名', fontsize=14, labelpad=10)
ax.set_ylabel('人口数', fontsize=14, labelpad=10)

ax.set_xticks(range(len(city)))
ax.set_xticklabels(['東京都', '横浜市', '大阪府', '名古屋市', '札幌市', '神戸市', '京都府', '福岡市', '広島市', '仙台市'], rotation=45)

ax.set_yticks([0, 5000000, 10000000, 15000000])
ax.grid(axis="y")

ax.text(6.5, 12000000, s="2019年時点のデータ\nになります", fontsize=10, horizontalalignment="left")

handles = [plt.Line2D([0], [0], color=color, lw=4) for color in region_colors.values()]
labels = region_colors.keys()
ax.legend(handles, labels, title="地域", bbox_to_anchor=(1.05, 1), loc='upper left')
<matplotlib.legend.Legend at 0x1690d6f60>
../_images/a5f1e845d832558ae16317e25d52f0e659ca768dd6b3a2fde21204772591230c.png

グラフの保存#

グラフを保存する場合、fig.savefig()メソッドを使用します。

保存する画像の形式は、ファイル名の拡張子から自動的に判断されます。.png以外には.jpg, .pdf, .svgが指定可能です。

fig.savefig()のメソッドの主なオプションを以下に示します。

オプション

説明

dpi

float

解像度 (dots per inch)

facecolor

str

背景の塗り潰し色

edgecolor

srt

枠線の色

transparent

boot

Trueの場合、背景が透明になる

#fig.savefig("./Figure/graph.png")

以下の図を再現してください

import pandas as pd
df=pd.read_csv("https://raw.githubusercontent.com/lvzeyu/css_tohoku/master/css_tohoku/draft/Data/titanic.csv")