(1) グラフ関連モジュールのインポート

Pythonにはグラフを描くためのモジュールがいくつか用意されていますが、このサイトではmatplotlibライブラリのpyplotモジュールを用いてグラフを表示する方法を学びます。

pyplotモジュールのインポート

コードセルの先頭に次のように書いて、pyplotモジュールをインポートし、コード内でpltという名前で使えるようにします。

import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ

matplotlibの日本語化

日本語化ライブラリのインストール

Google Colaboratoryのmatplotlibで日本語を表示しようとすると文字化けしてしまうので、日本語化のライブラリをインストールします。コードセルに次のコードを入力し、そのまま実行してください。


        # matplotlibを日本語化するためのライブラリをインストールします。
        # このファイルを開いたら、まずはこのコードセルを実行してください。
        # 今後「import japanize_matplotlib」の行でエラーが出たら、このコードセルを実行し直してください。
        !pip install japanize-matplotlib
      

Collecting japanize-matplotlib
  Downloading japanize-matplotlib-1.1.3.tar.gz (4.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 31.0 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/dist-packages (from japanize-matplotlib) (3.7.1)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (1.1.0)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (0.11.0)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (4.42.1)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (1.4.5)
Requirement already satisfied: numpy>=1.20 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (1.23.5)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (23.1)
Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (9.4.0)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (3.1.1)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib->japanize-matplotlib) (2.8.2)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.7->matplotlib->japanize-matplotlib) (1.16.0)
Building wheels for collected packages: japanize-matplotlib
  Building wheel for japanize-matplotlib (setup.py) ... done
  Created wheel for japanize-matplotlib: filename=japanize_matplotlib-1.1.3-py3-none-any.whl size=4120257 sha256=dd4a674f107092a60ae4ce6804fb5a3f29a44c8109705eada471a391776812f4
  Stored in directory: /root/.cache/pip/wheels/61/7a/6b/df1f79be9c59862525070e157e62b08eab8ece27c1b68fbb94
Successfully built japanize-matplotlib
Installing collected packages: japanize-matplotlib
Successfully installed japanize-matplotlib-1.1.3
      

このように、最後の行にSuccessfully・・・と表示されれば日本語化ライブラリのインストールが完了しました。今後、日本語化ライブラリのインポートのところでエラーが出たら、このコードを実行してください。

モジュールのインポート

コードセルの先頭に次のように書いて、pyplotモジュールをインポートし、コード内でpltという名前で使えるようにします。また、2行目で日本語かライブラリをインポートします。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ
      

(2) グラフの表示

グラフの表示

$x$座標と$y$座標の値をそれぞれ配列xと配列yに入れておき、plt.グラフ種類(x, y)でグラフを作成します。その後、plt.show()でグラフを表示します。

折れ線グラフの表示

折れ線グラフを作成するときは、plt.plot(x, y)で作成します。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ

        # データ
        x = [1, 2, 3, 4, 5]
        y = [2, 1, 5, 3, 4]

        # グラフの作成と表示
        plt.plot(x, y)  # 折れ線グラフを作成
        plt.show()      # グラフを表示する
      

棒グラフの表示

棒グラフを作成するときは、plt.bar(x, y)で作成します。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ

        # データ
        x = [1, 2, 3, 4, 5]
        y = [2, 1, 5, 3, 4]

        # グラフの作成と表示
        plt.bar(x, y)   # 棒グラフを作成
        plt.show()      # グラフを表示する
      

(3) グラフの設定

グラフの種類

代表的なグラフの種類の一部を紹介します。

グラフ種類 コード 説明
折れ線グラフ plt.plot() データを連続する線で表示します。時系列データなどの可視化によく使用されます。
棒グラフ plt.bar() 各カテゴリの値を棒で表示します。カテゴリごとの数量や頻度を比較するのに便利です。
水平棒グラフ plt.barh() 各カテゴリの値を水平な棒で表示します。
ヒストグラム plt.hist() データの分布を表示します。データの範囲を等間隔のビンに分割し、各ビンのデータ数を示します。
散布図 plt.scatter() 2つの変数の関係を点で表示します。
箱ひげ図 plt.boxplot() データの分布、中央値、最大値、最小値を表示します。外れ値の検出にも使われます。
円グラフ plt.pie() 各カテゴリの割合を円グラフで表示します。
エラーバー plt.errorbar() データの不確実性を示すエラーバーを含んだグラフを描画します。

その他のグラフの種類は、matplotlibの公式ドキュメントを参照してください。

グラフの書式

グラフの書式を設定するコードは、plt.show()より前に記述します。

グラフのタイトルと軸ラベル

次のコードでグラフのタイトルと軸ラベルを表示することができます。


        plt.title("グラフのタイトル")
        plt.xlabel("x軸のラベル")
        plt.ylabel("y軸のラベル")
      

次のコードでグラフの軸を表示することができます(これを入れないと、軸は表示されない)。lwは線の太さを指定します 。


        plt.axvline(0, color="black", lw=0.5)  # y軸(x=0の線)を表示
        plt.axhline(0, color="black", lw=0.5)  # x軸(y=0の線)を表示
      

plt.axvline(x, color, linestyle, linewidth)は座標xの位置に垂直線を描くために用います。基本的には上記のように軸を表示するために用います。また、plt.axhline(y, color, linestyle, linewidth)は座標yの位置に水平線を描くために用います。

colorは、"red""blue"などの色名のほか、カラーコード(#FF5733など)で指定します。

linestyleは、"-"(実線:デフォルト),"--":破線,":": 点線,"-.": 点と破線が使えます。

グラフの描画範囲

次のコードでグラフを描画する範囲を設定します。


        plt.xlim(0, 10)  # x軸を0〜10の範囲で描画
        plt.ylim(-5, 5)  # y軸を-5〜5の範囲で描画
      

グリッド線

次のコードでグラフのグリッド線を追加します。

plt.grid(True)

マーカーの書式と系列名

複数の系列がある場合、次のようにplt.plotを複数回呼び出します。また、このときマーカーの書式と系列名を指定します(系列名は後述の凡例で表示します。)。

折れ線グラフ

折れ線グラフでは、次のように書式を設定することができます。

plt.plot(x, y, marker="o", markersize=5, color="red", linewidth=1, label="系列名")

markerでは、マーカーの形を指定します("o": 円,"s": 四角形, "^": 三角形)。

markersizeでは、マーカーの大きさを指定します。

colorは、"red""blue"などの色名のほか、カラーコード(#FF5733など)で指定します。

linewidthでは、折れ線の太さを指定します。

散布図

        plt.scatter(x1, y1, color="red", s=10, label="系列1の系列名")   # 系列1のプロット
        plt.scatter(x2, y2, color="blue", s=20, label="系列2の系列名")  # 系列2のプロット
      

colorは、"red""blue"などの色名のほか、カラーコード(#FF5733など)で指定します。

sは、マーカーのサイズを指定します。

凡例

凡例の表示

凡例を表示するには、次のように書きます。

plt.legend()
凡例の位置

凡例の位置は自動で最適な位置に配置されますが、位置を指定したい場合はlocパラメータを用います。

plt.legend(loc="upper right")

locパラメータに指定可能な値は"upper right", "upper left", "lower left", "lower right", "right", "center left", "center right", "lower center", "upper center", "center" があります。

凡例の枠線

凡例の枠線を非表示にするには、frameon=Falseを指定します。

plt.legend(frameon=False)

グラフの大きさ

グラフの大きさを指定する場合は、plt.figure(figsize=(横, 縦))を指定します。

plt.figure(figsize=(10, 6))

グラフの保存・ダウンロード

グラフの保存

グラフを保存する場合は、plt.show()の前に次の保存する処理を書きます。保存先は、Google Colabの一時的な保管場所です。"ファイル名.png"のところは適宜変更してください。

plt.savefig("ファイル名.png", bbox_inches="tight")

bbox_inches="tight"はグラフの余白を小さくするためのオプションで、省略可能です。

グラフ画像のダウンロード

グラフ画像を自分のパソコンにダウンロードする場合は、Colabのfilesモジュールを使います。

from google.colab import files   # filesモジュールをインポート(コードセルの一番上に記述)
files.download("ファイル名.png") # 対象のファイルをダウンロードする(savefigのあとに記述)

(4) 関数とグラフ

NumPy

NumPy(Numerical Pythonの略)は、数値計算用のライブラリです。ここでは主に関数のグラフを描くときなどに用いますが、ほかにも配列や統計などに用いる機能も多くそろえています。

次の例では、NumPyの機能を用いてx-10から10まで0.1間隔で生成した値をxに格納したのち、yxの配列の各要素を2乗した値を格納しています。

import numpy as np   # NumPyをnpとしてインポート
x = np.arange(-10, 10, 0.1)  # -10から10まで0.1間隔で配列xに格納する。
y = x ** 2                   # 配列xの各要素を配列yに2乗して格納する。

NumPyを用いずにxの配列をループを用いずに生成すると、浮動小数点数の誤差が発生し、長い配列の場合には誤差が累積されて本来の値よりも誤差が大きくなります。このような現象を防ぐためにNumPyを用います。また、xはNumPy配列となり、y = x ** 2のように1行ですべての要素に対して2乗する操作を書くことができる上に、高速で効率的に計算されます(通常の配列だとforループを用いる必要があります)。

関数のグラフ

実習1 放物線

次の例では、$y=x^2$のグラフを表示します。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ
        import numpy as np              # numpy: 数値計算用のライブラリ

        # xとyの値を設定
        x = np.arange(-10, 10, 0.1)     # x: -10から10まで 0.1間隔
        y = x**2                        # y: y = x^2

        # グラフをプロット
        plt.plot(x, y, label="y = x^2")         # xとyの値をプロット
        plt.axhline(0, color="black", lw=0.5)   # y=0の線を描く
        plt.axvline(0, color="black", lw=0.5)   # x=0の線を描く
        plt.title("y = x^2のグラフ")            # グラフのタイトルを設定
        plt.xlabel("x")                         # x軸のラベルを設定
        plt.ylabel("y")                         # y軸のラベルを設定
        plt.legend(loc="lower left")            # 凡例を表示
        plt.grid(True)                          # グリッド線を表示

        plt.show()                              # グラフを表示
      

y = x**2のところをy = 2 * x**2 - 20 * x - 20などと変えてもう一度実行してみましょう。

実習2 サインカーブ

次の例では、$y=\sin x$のグラフを表示します。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ
        import numpy as np              # numpy: 数値計算用のライブラリ

        # 角度の値を生成: 0度から360度まで、1度間隔
        degrees = np.arange(0, 361, 1)

        # 角度をラジアンに変換
        radians = np.radians(degrees)

        # yの値を計算: y = sin(x)
        y = np.sin(radians)

        # グラフをプロット
        plt.plot(degrees, y, label="y = sin(x)")  # degreesとyの値をプロット
        plt.axhline(0, color="black", lw=0.5)  # y=0の線を描く
        plt.axvline(0, color="black", lw=0.5)  # x=0の線を描く
        plt.title("y = sin(x)のグラフ (x は角度)")  #s グラフのタイトルを設定
        plt.xlabel("角度 (度)")  # x軸のラベルを設定
        plt.ylabel("y")  # y軸のラベルを設定
        plt.legend()  # 凡例を表示
        plt.grid(True)  # グリッド線を表示

        # グラフを表示
        plt.show()
      

y = np.sin(radians)のところを、y = 2 * np.sin(2 * radians + np.pi / 8)などと変えてもう一度実行してみましょう。

2系列のグラフ

複数の系列を同時に表示するためには、次のようにy1, y2のNumPy配列を用意し、それぞれについてプロットを作成する記述plt.plot(x, y1, ...)plt.plot(x, y2, ...)を書きます。

実習3 挿入ソートとクイックソートの比較回数

挿入ソートの平均比較回数は $n(n-1)/4$,クイックソートの平均比較回数は$n \log_2{n}$ と表せます。次の例では、挿入ソートの平均比較回数とクイックソートの平均比較回数を比較するために2系列のグラフを表示します。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ
        import numpy as np              # numpy: 数値計算用のライブラリ

        # xの値を生成: 1から100までの整数値
        x = np.arange(1, 101)

        # yの値を計算
        y1 = x * (x - 1) / 4  # 挿入ソートの平均比較回数
        y2 = x * np.log2(x)  # クイックソートの平均比較回数

        # グラフをプロット
        plt.plot(x, y1, label="挿入ソート: n*(n-1)/4", color="blue")  # 挿入ソートのグラフをプロット
        plt.plot(x, y2, label="クイックソート): n*log2(n)", color="red")  # クイックソートのグラフをプロット
        plt.axhline(0, color="black", lw=0.5)  # y=0の線を描く
        plt.axvline(0, color="black", lw=0.5)  # x=0の線を描く
        plt.title("挿入ソートとクイックソートの比較回数のグラフ")  # グラフのタイトルを設定
        plt.xlabel("データ数")  # x軸のラベルを設定
        plt.ylabel("比較回数")  # y軸のラベルを設定
        plt.legend()  # 凡例を表示
        plt.grid(True)  # グリッド線を表示

        # グラフを表示
        plt.show()
      

媒介変数を用いたグラフ

実習4 円のグラフ

媒介変数$t$を用いると、円の$x$座標と$y$座標は次のように表すことができます。

\[ x = \cos t \] \[ y = \sin t \]

$t$を$-\pi$〜$+\pi$まで変化させたとき、$x$と$y$の値についてグラフを作成し表示します。

NumPyを用いて$-\pi$〜$\pi$まで1000等分した値を生成して配列tに格納するときは、t = np.linspace(-np.pi, np.pi, 1000)と書きます。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ
        import numpy as np              # numpy: 数値計算用のライブラリ

        t = np.linspace(-np.pi, np.pi, 1000)  # -π〜+πまで1000等分した値を生成

        # xとyの値を設定
        x = np.cos(t)
        y = np.sin(t)

        # プロット
        plt.figure(figsize=(6, 6))   # グラフの大きさを設定
        plt.plot(x, y)

        plt.show()
      

実習5 リサジュー曲線

互いに直行する二つの単振動を合成して得られる平面図形をリサジュー曲線といいます。リサジュー曲線は音波などの周波数の測定に用いられることが多く、基準波を横軸に、被測定波を縦軸に入力すると、上下に描かれた山の数と左右に描かれた山の数が基準波と被測定波の周波数比となって現れます。これを画面に表示したものがオシロスコープです。

簡単なリサジュー曲線の式は次の用に表すことができます。

\[ x = \sin (at + \delta) \] \[ y = \sin bt \]

媒介変数$t$が$-\pi$〜$+\pi$に変化すると、$x$と$y$の値が同時に変化します。

次の例では、$a=3$,$b=4$としたときのリサジュー曲線を表示します。


        import matplotlib.pyplot as plt # matplotlib: グラフを表示するためのライブラリ
        import japanize_matplotlib      # japanize_matplotlib: matplotlibを日本語化するためのライブラリ
        import numpy as np              # numpy: 数値計算用のライブラリ

        # パラメータの設定
        a = 3
        b = 4

        delta =  np.pi / 2  # 90度の位相差
        t = np.linspace(-np.pi, np.pi, 1000)  # -π〜+πまで1000等分した値を生成

        # リサジュー曲線の方程式
        x = np.sin(a * t + delta)
        y = np.sin(b * t)

        # プロット
        plt.figure(figsize=(6, 6))
        plt.plot(x, y)
        plt.title("Lissajous Curve")
        plt.xlabel("x")
        plt.ylabel("y")
        plt.axvline(0, color="black", lw=1)  # x軸
        plt.axhline(0, color="black", lw=1)  # y軸
        plt.grid(True)
        plt.show()
      

$a$,$b$の値を、$a=1$,$b=2$$a=5$,$b=4$などと変えてもう一度実行してみましょう。