Matplotlib は Python で最も広く使われているデータ可視化ライブラリの 1 つです。単純な可視化から複雑な可視化まで、ほとんどの場合、このライブラリが使用されています。
このチュートリアルでは、Matplotlib で、同じ Axes
や Figure
上に複数の折れ線グラフを描画する方法を見ていきます。
折れ線グラフの一般的な描画や、カスタマイズについてもっと知りたい方は、Matplotlib で折れ線グラフを描画するガイドを読んでください。
Matplotlib で複数の折れ線グラフを描画する
OOP スタイルか MATLAB スタイルかによりますが、 plt
インスタンス、または ax
インスタンスを使用してプロットします。
Matplotlib で複数の折れ線グラフを描画するには、単に plot()
関数を繰り返し呼び、同じ Figure
オブジェクトに変更を適用します。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5, 6]
y = [2, 4, 6, 5, 6, 8]
y2 = [5, 3, 7, 8, 9, 6]
fig, ax = plt.subplots()
ax.plot(x, y)
ax.plot(x, y2)
plt.show()
カスタマイズフラグを何も設定しなければ、デフォルトのカラーマップが適用され、両方の折れ線グラフが同じ Figure
オブジェクトに描画され、両者の色を区別するために調整されます。
さて、Numpy を使ってランダムな配列を生成し、折れ線グラフを少しカスタマイズして、それぞれに特定の色を設定し、ラベルを付けてみましょう。
import matplotlib.pyplot as plt
import numpy as np
line_1 = np.random.randint(low = 0, high = 50, size = 50)
line_2 = np.random.randint(low = -15, high = 100, size = 50)
fig, ax = plt.subplots()
ax.plot(line_1, color = 'green', label = 'Line 1')
ax.plot(line_2, color = 'red', label = 'Line 2')
ax.legend(loc = 'upper left')
plt.show()
その場合、0..n
の値が適用されます。ここで、n
はプロットするデータの最後の要素です。この例では、line_1
と line_2
という2つのデータ列があり、両方とも同じX軸にプロットされます。
プロットする際に、 color
引数で色を指定し、 label
引数で凡例用のラベルを指定しました。この結果、以下のようになります。
異なる尺度で複数の折れ線グラフをプロットする
折れ線グラフを描くのに適した 2 つのデータセットがあっても、その値が大きく異なっていて、両方の折れ線を比較するのが難しいことがあります。例えば、 line_1
が指数関数的に増加する数列で、 line_2
が直線的に増加する数列だったとしたら、きっとすぐに line_1
は line_2
よりはるかに大きな値になって、後者が見えなくなることだろう。
Numpyを使って指数関数的に増加する数列を作り、同じ Axes
上の別の線の隣に直線的にプロットしてみましょう。
import matplotlib.pyplot as plt
import numpy as np
linear_sequence = np.linspace(0, 10, 10)
# [0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 10]
exponential_sequence = np.exp(linear_sequence)
# [1.00e+00, 3.03e+00, 9.22e+00, 2.80e+01, 8.51e+01, 2.58e+02, 7.85e+02, 2.38e+03, 7.25e+03, 2.20e+04]
fig, ax = plt.subplots()
ax.plot(linear_sequence)
ax.plot(exponential_sequence)
plt.show()
このコードを実行すると、次のようになります。
指数関数的に増加する数列 exponential_sequence
は非常に速く比例しなくなり、もう一方の数列の指数関数的なトレンドに対して非常に小さいので、 linear_sequence
には全く違いがないように見えます。
ここで、exponential_sequence
を対数スケールでプロットしてみましょう。Yスケールが指数関数的に増加するので、視覚的に直線が生成されるでしょう。対数スケールでプロットして、 linear_sequence
が同じ定数だけ増加すると、2つの線が重なってしまい、最初の線の後にプロットされた線しか見えなくなってしまうでしょう。
そこで、 linear_sequence
を少し変更して、両方をプロットした後に観察できるようにしましょう。
import matplotlib.pyplot as plt
import numpy as np
# Sequences
linear_sequence = [1, 2, 3, 4, 5, 6, 7, 10, 15, 20]
exponential_sequence = np.exp(np.linspace(0, 10, 10))
fig, ax = plt.subplots()
# Plot linear sequence, and set tick labels to the same color
ax.plot(linear_sequence, color='red')
ax.tick_params(axis='y', labelcolor='red')
# Generate a new Axes instance, on the twin-X axes (same position)
ax2 = ax.twinx()
# Plot exponential sequence, set scale to logarithmic and change tick color
ax2.plot(exponential_sequence, color='green')
ax2.set_yscale('log')
ax2.tick_params(axis='y', labelcolor='green')
plt.show()
今回は、新しい Axes
インスタンスを作成するため、OOP インターフェイスを使用する必要があります。1 つの Axes
は 1 つのスケールを持つので、最初のものと同じ位置に新しいものを作成し、そのスケールを対数に設定して、指数関数列をプロットします。
この結果、次のようになります。
また、目盛りラベルの色を折れ線グラフの色と一致させるように変更しました。
複数の Y 軸を持つ複数の折れ線グラフをプロットする
最後に、同じスケール (線形、対数など) を適用して、それぞれの折れ線グラフの Y 軸に異なる値を持たせることができます。これは、異なる Axes
オブジェクトにある複数の Y 軸を同じ位置に配置することで実現します。
例えば、linear_sequence
は Y 軸が 20 以上にはなりませんが、exponential_sequence
は 20000 まで上がります。これらのオブジェクトはそれぞれ、入力されるデータに合わせて自動的に Y 軸の目盛りを設定します。
import matplotlib.pyplot as plt
import numpy as np
# Sequences
linear_sequence = [1, 2, 3, 4, 5, 6, 7, 10, 15, 20]
exponential_sequence = np.exp(np.linspace(0, 10, 10))
fig, ax = plt.subplots()
# Plot linear sequence, and set tick labels to the same color
ax.plot(linear_sequence, color='red')
ax.tick_params(axis='y', labelcolor='red')
# Generate a new Axes instance, on the twin-X axes (same position)
ax2 = ax.twinx()
# Plot exponential sequence, set scale to logarithmic and change tick color
ax2.plot(exponential_sequence, color='green')
ax2.tick_params(axis='y', labelcolor='green')
plt.show()
もう一度、最初のものと同じ位置に別の Axes
を作成しました。これにより、Figure
の同じ場所に、異なる Axes
オブジェクトでプロットすることができ、それぞれの Y 軸に個別に値を設定することができます。
今回、Yスケールを対数に設定しなければ、両方とも線形にプロットされます。
結論
このチュートリアルでは、Matplotlib と Python で、同じ Figure
や Axes
に複数の折れ線グラフをプロットする方法について解説してきました。同じ Axes
上に同じスケールと Y 軸でプロットする方法と、同じ Figure
上に異なるスケールと同じ Y 軸でプロットする方法について説明しました。
データ可視化に興味があるが、何から始めたらいいかわからないという方は、Pythonによるデータ可視化に関する書籍のバンドル版をぜひご覧ください。
Pythonによるデータ可視化
データビジュアライゼーションで危険な存在になる
30日間無条件返金保証
初級から上級まで
定期的に無料で更新(最新更新は2021年4月)
ボーナスリソースやガイドを更新
Pythonでデータ可視化 MatplotlibとPandasは、Pythonの基礎知識を持つ全くの初心者が、PandasとMatplotlibを使って、単純なプロットからインタラクティブなボタンを持つアニメーションの3Dプロットまで、これらのライブラリで高度な作業をするための強力な基盤を構築できるように設計された書籍です。
本書は、Pythonの基本的な知識を持つ方を対象としています。
PandasとMatplotlibについて知っておく必要があることすべてを教えてくれる詳細なガイドです。
Pythonでデータ可視化」は、Pythonの初級~中級開発者向けの本で、Pandasを使った簡単なデータ操作から、MatplotlibやSeabornといったコアなプロットライブラリを取り上げ、Altairのような宣言的・実験的なライブラリの活用方法まで、幅広くガイドしています。具体的には、11章にわたって、9つのPythonライブラリを取り上げています。Pandas、Matplotlib、Seaborn、Bokeh、Altair、Plotly、GGPlot、GeoPandas、そしてVisPyです。
データビジュアライゼーションのユニークで実用的なガイドとして、あなたがキャリアで使うかもしれない多くのツールを紹介しています。