Matplotlibで簡単に棒グラフを表示する方法【Python】

Matplotlibで簡単に棒グラフを表示する方法【Python】 プログラミング

この記事では、Matplotlibで棒グラフを作成する方法を説明していきます。
しかし、単純にMatplotlibの関数説明に終わるだけでは味気ないです。
それなら、マニュアルを見るだけで十分です。

そこで、実際に公開されている棒グラフを作成してみることにします。
その過程で実践的な知識を身に付けることが可能だと思います。
対象となるのは、ウィキペディア(Wikipedia)の「棒グラフ」ページのグラフです。

【グラフA】2004年の選挙結果を示した棒グラフ

wikiの2004年の選挙結果を示した棒グラフ

【グラフB】2004年の結果と1999年の結果の両方を示した棒グラフ

wikiの2004年の結果と1999年の結果の両方を示した棒グラフ

上の2つのグラフ(グラフA、グラフB)をMatplotlibを利用して作成していきます。

本記事の内容

  • そもそも、棒グラフを使う必要がありますか?
  • Matplotlibで棒グラフを表示するための環境
  • グラフAの棒グラフをMatplotlibで作成する
  • グラフBの棒グラフをMatplotlibで作成する

この記事の通りに行えば、冒頭のグラフを作成できるようになります。
それでは、説明を行っていきます。

そもそも、棒グラフを使う必要がありますか?

「早く棒グラフの作り方を教えろ!!」という方はこの項を無視してください。

棒グラフとは?

英語では、bar chartまたはbar graphと表現します。

特徴は、数量を棒の長さで表したグラフということです。
そのため、数量の大きさを視覚的に捉えやすいという利点があります。

棒グラフを使うとどうなる?

  • 2つ以上の値を比較しやすい
  • 全体の傾向や特徴を捉えやすい

特に重要なのは、簡単に比較ができるということですね。
2つだけではなく、3つ以上の数値を一瞬で比較することが可能です。

Matplotlibで棒グラフを表示するための環境

  • Windows 10 Home (バージョン1909)※以下の説明は64bit前提
  • Python 3.7.3
  • Matplotlib 3.2.1
  • NumPy 1.18.5

matplotlibでグラフに日本語が表示できない場合は、次の記事をご覧ください。

Numpyをインストールしていなければ、インストールしてください。
次のコマンドで簡単にインストールできます。

pip install numpy

グラフAの棒グラフをMatplotlibで作成する

グラフAとグラフBを作成するためには、元となるデータが必要です。
以下のデータを利用します。

政党議席数 (2004)議席数 (1999)
EUL3949
PES200210
EFA4256
EDD1519
ELDR6760
EPP276272
UEN2736
その他6629

このデータをもとにして、早速グラフAを作成していきます。

データをもとに棒グラフを表示する

次のコードを実行します。

import numpy as np
import matplotlib.pyplot as plt

labels = ['EUL', 'PES', 'EFA', 'EDD', 'ELDR', 'EPP', 'UEN', 'その他']
values = [39, 200, 42, 15, 67, 276, 27, 66]
lefts = np.arange(len(values))

plt.bar(lefts, values, tick_label=labels)

上のコードを実行するだけ、次の棒グラフが作成されます。
簡単に説明しておきます。

単純な棒グラフ

labelsとvaluesは説明不要ですね。
leftsは説明が必要でしょう。

leftsの中身は以下。
[0 1 2 3 4 5 6 7]

leftsは、labelsのx座標の配列です。
valuesは、labelsのy座標の配列です。

x座標を求めるために、単純にlabelsの個数から求めているだけです。

でも、グラフAと比較すると次の表示が不足しています。
タイトル、横軸ラベル、縦軸ラベルということですね。

  • European Paliament 2004
  • Group
  • Seats

次は、これらの項目をグラフに表示してみます。

棒グラフにタイトル、横軸ラベル、縦軸ラベルを表示させる

せっかくなので、表示を日本語に変えましょう。

  • 欧州議会選挙 2004
  • 政党
  • 議席数

コードは以下です。

import numpy as np
import matplotlib.pyplot as plt

labels = ['EUL', 'PES', 'EFA', 'EDD', 'ELDR', 'EPP', 'UEN', 'その他']
values = [39, 200, 42, 15, 67, 276, 27, 66]
lefts = np.arange(len(values))

plt.bar(lefts, values, tick_label=labels)
plt.title("欧州議会選挙 2004")
plt.xlabel("政党")
plt.ylabel("議席数")

実行結果。

タイトルやラベルを追加した棒グラフ

縦軸のラベルが、イマイチですね。
でも、ここではこれで我慢しましょう。

ここからは、外見を合わせていきます。

見た目を近づける

棒グラフの幅を小さくする

引数にwidthを追加します。
ちなみに、widthの初期値は0.8です。

plt.bar(lefts, values, tick_label=labels)

plt.bar(lefts, values, tick_label=labels, width=0.5)

widthを0.5に設定して実行した結果。

グラフの幅を小さくした棒グラフ

いい感じの幅になりました。
では、次は色を変更します。

棒グラフの色を変更する

引数にcolorを追加します。

plt.bar(lefts, values, tick_label=labels, width=0.5)

plt.bar(lefts, values, tick_label=labels, width=0.5, color="#b2b2b2")

colorにカラーコード#b2b2b2を設定して実行した結果。

グラフの色を変更した棒グラフ

あと、大きなところは枠線ですね。
上と右の枠線がを消しましょう。

棒グラフから右と上の枠線を消す

最後に以下のコードに追加します。

plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

実行結果。

枠線を消した棒グラフ

見事に枠線が消えました。

まとめ

まだまだ、調整したいところはあります。
ただ、今回はこのぐらいにして、グラフAは終わりにしましょう。

グラフAを出力するコードは以下。

import numpy as np
import matplotlib.pyplot as plt

labels = ['EUL', 'PES', 'EFA', 'EDD', 'ELDR', 'EPP', 'UEN', 'その他']
values = [39, 200, 42, 15, 67, 276, 27, 66]
lefts = np.arange(len(values))

plt.bar(lefts, values, tick_label=labels, width=0.5, color="#b2b2b2")
plt.title("欧州議会選挙 2004")
plt.xlabel("政党")
plt.ylabel("議席数")

plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

グラフBの棒グラフをMatplotlibで作成する

実現方法は、シンプルです。
棒グラフを2つ作成して、それを並べます。

単純に2つ表示すると棒グラフが重なってしまいます。
そのため、それぞれ棒グラフが重ならないように表示位置を調整する必要が出てきます。

ここ位置調整の理解の部分が、ポイントとなります。

データを用意する

まずは、データを用意します。

labels = ['EUL', 'PES', 'EFA', 'EDD', 'ELDR', 'EPP', 'UEN', 'その他']
values_1999 = [49, 210, 56, 19, 60, 272, 36, 29]
values_2004 = [39, 200, 42, 15, 67, 276, 27, 66]

グラフの表示位置を調整する

1999年分、2004年分データの位置を求めるコードは以下。
グラフ幅を0.5としています。

lefts_1999 = np.arange(len(values_1999))
lefts_2004 = lefts_1999 + 0.5

この時点でのコードは以下。

import numpy as np
import matplotlib.pyplot as plt

labels = ['EUL', 'PES', 'EFA', 'EDD', 'ELDR', 'EPP', 'UEN', 'その他']
values_1999 = [49, 210, 56, 19, 60, 272, 36, 29]
values_2004 = [39, 200, 42, 15, 67, 276, 27, 66]

lefts_1999 = np.arange(len(values_1999))
lefts_2004 = lefts_1999 + 0.5

plt.bar(lefts_1999, values_1999, tick_label=labels, width=0.5, color="#666666")
plt.bar(lefts_2004, values_2004, tick_label=labels, width=0.5, color="#b2b2b2")
        
plt.title("欧州議会選挙")
plt.xlabel("政党")
plt.ylabel("議席数")

plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

実行結果は以下。

2つのグラフを並んで表示した棒グラフ

グラフの幅を小さくすれば、適当なスペースができます。
グラフの幅を小さくします。
現状、0.5のwidthを0.35に変更して再度実行。

位置表示を調整した棒グラフ

いい感じに間隔も広がりました。
でも、政党名のラベル位置がずれています。

なお、widthを変数扱いにした方がコードを書きやすいです。
g_widthがグラフ幅を指定した変数。
この時点でのコードは以下。

import numpy as np
import matplotlib.pyplot as plt

labels = ['EUL', 'PES', 'EFA', 'EDD', 'ELDR', 'EPP', 'UEN', 'その他']
values_1999 = [49, 210, 56, 19, 60, 272, 36, 29]
values_2004 = [39, 200, 42, 15, 67, 276, 27, 66]

g_width = 0.35

lefts_1999 = np.arange(len(values_1999))
lefts_2004 = lefts_1999 + g_width

plt.bar(lefts_1999, values_1999, tick_label=labels, width=g_width, color="#666666")
plt.bar(lefts_2004, values_2004, tick_label=labels, width=g_width, color="#b2b2b2")
        
plt.title("欧州議会選挙")
plt.xlabel("政党")
plt.ylabel("議席数")

plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

横軸のラベル位置を調整する

現状のラベル表示は以下のコードで行っています。

plt.bar(lefts_1999, values_1999, tick_label=labels, width=g_width, color="#666666")
plt.bar(lefts_2004, values_2004, tick_label=labels, width=g_width, color="#b2b2b2")

どうやら、最後の表示が優先される仕様のようです。
つまり、2004年データの棒グラフを表示する際の位置指定だということです。

そもそも、グラフを並べる場合は、このような指定はやめておきましょう。
以下のコードで表現しましょう。

plt.xticks(lefts_1999 + g_width/2, labels)

よって、コードを以下のように変更します。
tick_labelをplt.barの引数から除去しています。

plt.bar(lefts_1999, values_1999, width=g_width, color="#666666")
plt.bar(lefts_2004, values_2004, width=g_width, color="#b2b2b2")

plt.xticks(lefts_1999 + g_width/2, labels)

これで実行すると以下の結果となります。

横軸のラベルを調整した棒グラフ

政党を表す横軸のラベルも適切に表示されています。
残るは、「凡例」ですね。
これを対応して、終わりにしましょう。

凡例を表示する

import numpy as np
import matplotlib.pyplot as plt

labels = ['EUL', 'PES', 'EFA', 'EDD', 'ELDR', 'EPP', 'UEN', 'その他']
values_1999 = [49, 210, 56, 19, 60, 272, 36, 29]
values_2004 = [39, 200, 42, 15, 67, 276, 27, 66]

g_width = 0.35

lefts_1999 = np.arange(len(values_1999))
lefts_2004 = lefts_1999 + g_width

p_1999 = plt.bar(lefts_1999, values_1999, width=g_width, color="#666666")
p_2004 = plt.bar(lefts_2004, values_2004, width=g_width, color="#b2b2b2")
        
plt.xticks(lefts_1999 + g_width/2, labels)
        
plt.title("欧州議会選挙")
plt.xlabel("政党")
plt.ylabel("議席数")

plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

plt.legend((p_1999[0], p_2004[0]), ("1999", "2004"), loc='upper center', ncol=2)

このコードの結果は以下。

これでグラフBの作成方法は完了です。
まだまだ、完成度を高める余地は残っています。

しかし、この記事ではこの完成度で終わりとします。

タイトルとURLをコピーしました