【Python】matplotlibでグラフを作成する方法【総まとめ】

Python用のグラフ描画ライブラリ「matplotlib」を使ってグラフを描く方法の総まとめメモです。基本的なプロットを中心に、色々なグラフを描いてみましょう。


 

 matplotlibの基本と2つの流儀

matplotlibはPythonで静的なプロットやアニメーション、インタラクティブな可視化を実現するための包括的なライブラリです。Pythonでグラフを描画するときは、取り敢えずmatplotlibを使っておけば間違いありません。

ここでは既にnumpyおよびmatplotlibライブラリが導入されているものとして使い方を解説していきます。導入自体はpipインストーラなどで可能ですし、Anacondaで環境構築している場合はcondaで導入可能です。

matplotlibライブラリは以下のようにインポートします。matplotlibに梱包されているpyplotモジュールはpltという名称で置換するのが慣例になっています。

例えば折れ線グラフは次のようにすれば表示できます。$(x,y)$の点列を黒線で繋いだだけのプロットです。以下のコードでは座標の値をリストで渡していますが、numpyの配列としても渡すことができます。


ところで、matplotlibにはグラフを作る上で2つの流儀が存在するということは知っておくべき事項です。

一つは「Pyplotインターフェース」と呼ばれるもので、MATLABに近い書き方ができます。元々matplotlibはMATLABに準ずる描画機能をPythonで実現するために開発されてきた経緯があり、pyplotモジュールから直接関数を呼び出す方式なので書き方はこちらの方がシンプルです。ただし簡単に描ける分、プロットの自由度は限定的です。

もう一つは「オブジェクト指向インターフェース」と呼ばれるものです。この記法は下図のように階層構造にしてグラフを描画するもので、こちらの方が図の細かい調整には向いています。イメージとしては、Figureオブジェクト(画板)の中にAxesオブジェクト(台紙)があり、その上にタイトルや凡例、軸ラベルなどのオブジェクトを出力するという形でプロットを表示します。

ネット上のコードはこれら2つの記法が綯い交ぜになっており、コピペしただけでは狙った挙動にならず変な所でハマってしまう危険性があります。こうしたことを避けるためにも、まずはmatplotlibの記法には2種類の流儀が存在することをよく覚えておきましょう。

ここでは簡便なPyplotインターフェースを主に採用してサンプルコードを掲載していますが、見栄えを重視するのであれば、普段からオブジェクト指向インターフェースを利用して慣れておくことを推奨します。特に理由が無ければオブジェクト指向インターフェースに統一すべきという意見もあります。

 

 色・線種・マーカーの指定

色や線種、マーカーはplotメソッドの引数として指定します。例えば以下のようにとすると、青色の実線で関数 $y=x^2$ が描かれます。

matplotlibではカラーコードを指定すればどんな色でも使えますが、よく使われる色には特別な名前が付けられています。使用できる色と名前は以下の通りです。

(公式ドキュメントはこちら


また、線種の一覧は以下の通りです。

記法 線種
ls=”:” 点線
ls=”-.” 一点鎖線
ls=”–“ 破線
ls=”-“ 実線

(公式ドキュメントはこちら


matplotlibには以下のように多数のマーカーが用意されています。

記法 マーカー
marker=”.”
marker=”,” ピクセル
marker=”o”
marker=”v” 下三角形
marker=”^” 三角形
marker=”<“ 左三角形
marker=”>” 右三角形
marker=”s” 四角形
marker=”p” 五角形
marker=”h” 六角形
marker=”8″ 八角形

(つづき)

記法 マーカー
marker=”*”
marker=”1″ Y
marker=”2″ Y(上下反転)
marker=”3″ Y(90度時計回り)
marker=”4″ Y(90度反時計周り)
marker=”+” +
marker=”x” x
marker=”X” x(filled)
marker=”D” ひし形
marker=”d” 細いひし形
marker=”” マーカー無し

(公式ドキュメントはこちら


例えば以下のようなコードを走らせると下図のようなプロットが得られます。

他にもplotメソッドの引数を与えてマーカーの透明度を操作したり、ラベルのフォントを変更できたりします。是非色々遊んでみて下さい。

 

 折れ線&曲線のグラフ

折れ線グラフで点と線の色を変えたいときは別々に描画するか、括弧内に「$x$座標, $y$座標, 書式」の順に2回書きます。


曲線のグラフは定義域内に多数の点を取って線を結ぶという方法で描画します。そのため、$x$座標の配列を用意する必要があります。以下の例では np.arange(0.0, 5.0, 0.02) として$0$~$5$までの区間に$0.02$の間隔で$250$個の点を生成して描画しています。

画素数や曲線の曲率にも依りますが、$f(x)=e^{-x}\cos 2\pi x$ 程度なら$250$点も取れば十分滑らかに見えます。$100$点くらいだとカーブがやや角ばりますが、何万点もサンプリングする必要はありません。丁度良い塩梅になるように適宜調整しましょう。

 

 棒グラフ

以下は、1920年から2020年にかけての世界の総人口の推移を棒グラフで出力するコードです。日本語を表示するためにごちゃごちゃやっていますが、本質部分はbar()関数です。widthは棒の幅、colorは塗りつぶし色、edgecolorは枠線の塗りつぶし色、linewidthは棒の枠線の太さ、tick_labelは横軸のラベル、hatchは棒の模様を指定するパラメータです。

積み上げ棒グラフ(Stacked barplot)を描くのはやや複雑です。

(データの出典:Wikipedia)

 

 円グラフ

円グラフの描画は次のようにします。pie()関数は引数が多く、使いこなすのが難しいかもしれません。ここで、plt.pieは (patches, texts, autotexts)のタプルを返します。textsがlabalデータなので、この変数にフォントを割り当てています。

中央に新たな円を追加すればドーナツ型の円グラフが得られます。

 

 ヒストグラム

サイコロを$10$回振って出た目の総和を横軸とし、総和の値が現れた回数を縦軸にとった分布を以下に示します。累積値が多いほど縦軸が伸びます。このようなグラフをヒストグラムと呼びます。

rwidthは棒の画像的な幅を指定する値で、デフォルトでは$1$です。binsは棒の数値的な幅(積算する範囲)を指定する値です。

この例に関して言えば、rangeの値を大きくして試行回数を増やすと(乱数が一様にランダムに生成される限り)二項分布が正規分布に近づく様子を観察することができます。

 

 散布図とカラーバー

scatter()関数で散布図が描けます。scatter()関数には幾つか引数を与えることができ、sで点の大きさを、cで色を、alphaで透明度を指定できます。

散布図に複数のプロットを描くこともできます。

重ね描きすれば以下のように幾らでもプロットの種類を増やせますが、分かりやすくするために凡例を付けるべきですね。


プロットする点の大きさや色はデータの値に応じて変えることができます。入力データが第$3$軸方向の値を持つ場合はカラーバーを併記して出力することをお勧めします。

上図ではカラーマップのパラメータを cmap=’viridis’ と指定していますが、他にも “plasma” や “jet”、”gnuplot” などが見やすいと思います。以下にcmapのパラメータ一覧を載せておくので試してみて下さい。

» cmapのパラメータ一覧


Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens, Greens_r, Greys, Greys_r, OrRd, OrRd_r, Oranges, Oranges_r, PRGn, PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Purples, Purples_r, RdBu, RdBu_r, RdGy, RdGy_r, RdPu, RdPu_r, RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spectral, Spectral_r, Wistia, Wistia_r, YlGn, YlGnBu, YlGnBu_r, YlGn_r, YlOrBr, YlOrBr_r, YlOrRd, YlOrRd_r, afmhot, afmhot_r, autumn, autumn_r, binary, binary_r, bone, bone_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, cool, cool_r, coolwarm, coolwarm_r, copper, copper_r, cubehelix, cubehelix_r, flag, flag_r, gist_earth, gist_earth_r, gist_gray, gist_gray_r, gist_heat, gist_heat_r, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gnuplot, gnuplot2, gnuplot2_r, gnuplot_r, gray, gray_r, hot, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, seismic, seismic_r, spring, spring_r, summer, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terrain, terrain_r, twilight, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, winter, winter_r

※これで全部という訳ではないので、ご注意下さい!


» 閉じる

(カラーマップの公式ドキュメントはこちら

 

 ヒートマップ

色合いや濃淡で2次元データの個々の値を表示した分布図をヒートマップと呼びます。グリッドを定義するのが面倒ですが、物性値を調べる上では散布図よりも役立つことが多い表現方法です。

(公式ドキュメントはこちら、デモコードはこちら

 

 複数の線を表示する

plotメソッドで複数回書き出すことで、複数の曲線を同じ平面上に表示することができます。

 

 等高線&濃淡のある等高線

matplotlibでは等高線をフレキシブルに描画することができます。ここでは例として「Müller-Brownポテンシャル曲面*」を描いてみます。np.linspaceでどのくらい細かくメッシュを定義するかによって等高線の滑らかさが変わります。

デフォルトだと上図のようなグラデーションになります。等高線の色はcolorsで任意に指定可能ですが、このとき等高線の数に合わせてリスト型で色を指定して下さい。cmapで色調のプリセットを指定しても良いでしょう。

また、領域を塗りつぶすときはcontour関数の代わりにcontourf関数を用います。

例えば、contourf関数の引数として cmap=’plasma’ を指定すると以下のような色合いになります。


*参考:K. Müller and L. D. Brown, “Location of Saddle Points and Minimum Energy Paths by a Constrained Simplex Optimization Procedure,” Theoretical Chemistry Accounts, 53, 1979 pp. 75–93.

 

 3Dのグラフを表示する

mpl_toolkits.mplot3dからAxes3Dをインポートすることで3次元グラフに対応します。

メッシュグリッドを定義すれば曲面も描画できます。

3次元散布図も描画できます。

頑張ればこんなのも描けます。(公式ドキュメントのコードを一部改変しています)

(mpl_toolkits.mplot3d.axes3d.Axes3Dの公式ドキュメントはこちら

 

 複数のグラフを並べる

これまで紹介してきたコードにも何度か登場していますが、subplotという関数によってグラフの位置を規定することができます。例えばsubplot(2,2,3)の場合は「$2 \times 2$ の$3$番目の位置」を意味します。基本的にはどのような種類のグラフを載せようとも、位置の割り当て方は同じです。

 

 最後に

グラフが鮮やかであることと読み取りやすさは比例しません。グラフはデータを可視化して効率良く情報を読み取ることを助けますが、場合によってはデータの意味を取り違えてしまったり、情報の本質を見落としてしまうことに繋がったりしかねません(中には意図的にミスリードを誘うようなグラフが作られる悪質な例もあります)。どのようなデータがどのようなグラフによる可視化に向いているのかを知っておくことはmatplotlibを使う以前の事柄であり、グラフに騙されないためにも大切です。

ご覧の通り、matplotlibは高品質なグラフ描画機能を提供するパッケージであり、Pythonで可視化するならmatplotlib、というのが事実上のスタンダードです。最近話題に上がることの多くなってきたJulia言語でもPyPlotパッケージからmatplotlibを呼び出せます。matplotlibの使い方に慣れておくことは様々なデータを可視化していく上で非常に重要であり、将来ますます使用頻度が高くなることでしょう。今後、皆さんがmatplotlibを使うにあたって、本稿の内容が役立てば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です