Phython

【matplotlib】誰でも簡単にpythonで棒グラフを作成する方法

pythonはデータ解析に非常に特化しており、さまざまな形のグラフを簡単に作成することが出来ます。

今回は、その中でも『棒グラフ』に焦点を当てていろいろな種類の棒グラフの作成方法やグラフのカスタマイズについてご紹介していこうと思います。

初心者の方でも、すべて理解できるようにわかりやすく解説しているので、ぜひ最後までご覧ください。

この記事でわかること

  • 基本的な棒グラフの作成方法
  • 棒グラフに対するさまざまなカスタマイズ

 グラフ作成の準備

実際に棒グラフを作成する前に、少し下準備が必要です。
興味がある方は、手元を動かして一緒に動作を確認して理解を深めていきましょう。


必要なライブラリのインポート

今回使用するライブラリは、numpyとmatplotlibです。
下記コードを記述してインポートしていきます。

import numpy as np
import matplotlib.pyplot as plt

ここで、numpy・matplotlibって何?という方は、ぜひ下記の記事を参考にしてみてください。
それぞれのライブラリの説明と、使い方を初心者の方でもわかりやすいように紹介しています。

これで今回行う下準備は完了です。
早速棒グラフ作成の方に移っていきましょう。

 基本的な棒グラフの作成

まず、基本的な棒グラフの作成方法をご紹介していこうと思います。
基本的なといっても様々なカスタマイズ方法について触れているので、参考にしてみてください。

縦棒グラフの作成

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) #x=[0, 1, 2, ..., 9]
y = np.random.uniform(1, 10, 10) #1~10の範囲で一様に分布した乱数

plt.bar(x, y) #棒グラフ作成
plt.show()

<output>

上記のコードのように、plt.bar(x, y)によって棒グラフを作成することが出来ます。
今回は、棒グラフの高さを1~10の範囲でランダムに設定していますね。

複数の棒グラフ作成

また、以下のようなコードを書くと棒グラフを同じ平面に二つ作成することが出来ます。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y1 = np.random.uniform(1, 10, 10) 
y2 = np.random.uniform(1, 10, 10)

width = 0.3 #棒グラフの幅
shift = width/2 #ずらす幅

plt.bar(x - shift, y1, width)
plt.bar(x + shift, y2, width)
plt.show()

<output>

棒グラフの場合、関数グラフや散布図等と異なり、ただ二つのグラフを作成しようとすると同じ場所に作られてしまうため、うまく両方の棒グラフを表示することが出来ません。
なので、棒グラフを作成する場所を少しずらして隣に表示させてあげる必要があります。

目盛り・表示範囲の指定

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y = np.random.uniform(1, 10, 10) 
X = [1,2,3,4,5,6,7,8]
Y = [0,1,2,8,9,10]

plt.bar(x, y)
plt.xlim(1,8) #グラフ表示の範囲指定
plt.xticks(X) #x軸の目盛り作成
plt.yticks(Y) #y軸の目盛り作成
plt.show()

<output>

xlim()やylim()で表示する範囲の指定、xticks()やyticks()で目盛りの作成が行えます。

ちなみに、以下のようなコードを作成すると、目盛りを完全に消すことも可能です。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y = np.random.uniform(1, 10, 10) 
X = []
Y = []

plt.bar(x, y)
plt.xticks(X) #x軸の目盛り作成
plt.yticks(Y) #y軸の目盛り作成
plt.show()

<output>

補助線の導入

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y = np.random.uniform(1, 10, 10) 
X = [0,1,2,3,4,5,6,7,8,9]
Y = [0,1,2,3,4,5,6,7,8,9]

plt.bar(x, y)
plt.xticks(X)
plt.yticks(Y)

plt.grid(axis='x', color='gray', linewidth=0.5) #x軸の目盛り方向にグレー色で幅0.5の実線を引く
plt.grid(axis='y', color='gray', linewidth=0.5) #y軸の目盛り方向にグレー色で幅0.5の実線を引く

plt.show()

<output>

plt.grid()という関数を使うと、それぞれの棒グラフの高さを見やすくすることが出来ます。

また、下記のコードを記述することで、補助線のようなものも書くこともできます。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y = np.random.uniform(1, 10, 10) 
X = [0,1,2,3,4,5,6,7,8,9]
Y = [0,1,2,3,4,5,6,7,8,9]

plt.bar(x, y)
plt.xticks(X)
plt.yticks(Y)

plt.axhline(5, xmin=-1.0, xmax=1.0, color='r', linestyle=':') #y=5の地点に補助線を引く
                                  #xmin、xmaxはそれぞれどこまで引くのかを指定している
                                  #colorは色、linestyleは線のスタイルを指定している

plt.show()

<output>

横棒グラフ

plt.bar()の代わりにplt.barh()を使用することで、縦棒ではなく横棒のグラフを作成することが出来ます。
それ以外は特に何も変わることはありません。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y = np.random.uniform(1, 10, 10) 
X = [0,1,2,3,4,5,6,7,8,9]
Y = [0,1,2,3,4,5,6,7,8,9]

plt.barh(x, y) #横棒グラフ
plt.xticks(X)
plt.yticks(Y)

plt.show()

<output>

色の指定方法

ここからは、棒グラフを色を変更していこうと思います。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y = np.random.uniform(1, 10, 10) 
X = [0,1,2,3,4,5,6,7,8,9]
Y = [0,1,2,3,4,5,6,7,8,9]

plt.bar(x, y, color = 'r') #引数colorで色変更
plt.xticks(X)
plt.yticks(Y)

plt.show()

<output>

色の変更に関しては、他のグラフと同じやり方で行うことが出来ます。

棒グラフの色分けを行う

色の指定方法によって、棒グラフをよりカラフルに作ることが出来ます。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(7) 
y = np.random.uniform(1, 10, 7) 
X = [0,1,2,3,4,5,6]
Y = [0,1,2,3,4,5,6]
colors = ['b','g','r','c','m','y','k'] #色に関する配列作成

plt.bar(x, y, color = colors)
plt.xticks(X)
plt.yticks(Y)

plt.show()

<output>

こんな感じです。
今回は、一文字で表現できる色を7色使ってグラフを作成してみました。

棒グラフのグラデーション

続いて、少しおしゃれなグラデーションなんてどうでしょう。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10) 
y = np.random.uniform(1, 10, 10) 
X = [0,1,2,3,4,5,6,7,8,9]
Y = [0,1,2,3,4,5,6,7,8,9]

colors = []
for i in range(10): #i=0~9
  colors.append((1.0 - i/10, 0, i/10)) #colors(r,g,b)で指定

plt.bar(x, y, color = colors)
plt.xticks(X)
plt.yticks(Y)

plt.show()

<output>

新しいコードがいくつか出てきたので軽く紹介します。

まず、10行目ですが、こちらは「iに0から9までを代入して11行目の操作を繰り返し行うよ」といった命令になっています。
要するに、『colors.append((1.0 - i/10, 0, i/10))』のiの部分に0を代入、1を代入、2を代入、,,,、9を代入といった感じで11行目の命令を10回繰り返していることになります。

ちなみに、11行目の処理ですが、『append』が配列に新しい要素を追加する操作を行うものなので、この処理が終わったころにはcolorという配列に10個の要素が加わっているといった感じです。

なので、colorsという配列に微妙に違う値が毎度追加されていることになるんですね。
それを用いて、グラデーションを作成しています。

カラーマップによるグラデーション

続いて、カラーマップを使って同じようにグラデーションを作ってみます。

<input>

import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt

for x in range(10): #x=0~9
    y = np.random.uniform(1, 10, 1) #yに0~10までの数値をランダムに一つ代入
    plt.bar(x, y, color=cm.winter(x/10)) #wintercolormapの特徴量を徐々に増やす


plt.show()

<output>

先ほどと同様にfor文を用いて、colorに代入する色を徐々に変化させていますね。
また、カラーマップを利用するために『matplotlib.cm』を新たにインポートしているので試してみたいという方は注意してください。

条件で色を変更する

続いて、自分で条件を指定して条件ごとを満たすかどうかでグラフの色を変更するという処理を書いてみます。

<input>

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y = np.random.uniform(-10, 10, 10)

colors = []

for i in range(10): #i=0~9
  if y[i]>=0:                   #もし、y[i]が0以上ならば
    colors.append((0, 0, 1.0))  #グラフの色を青色に
  else :                        #そうでなければ(もしy[i]が0以上じゃなければ)
    colors.append((1.0, 0, 0))  #グラフの色を赤色に

plt.bar(x, y, color=colors)

plt.show()

<output>

このように、if文を用いると条件による色の変更も行えるようになります。
今回は、グラフのy座標(高さ)が0以上であれば青色に設定、0未満であれば赤色に設定といった感じですね。

 棒グラフ応用例|実際のデータに対して棒グラフを用いて分析

続いて、実際のデータに対して棒グラフを用いてデータの分析をしていきましょう。

ですがその前に、データの準備等を行う必要があります。
データの準備方法から、使用するデータの説明まで順番に見ていきましょう。

pandasのインポート・使用するデータの準備

まず、今回の分析に必要なデータとデータ読み込みに必要なpandasというライブラリの用意を行います。

pandasについてよくわからない方は、初心者の方でも理解できるようにpandasの説明を行っているので、以下の記事を参考にしてみてください。
また、以下の記事も今回と同じデータを使っているので、データの取り込み方につきましても、この記事を参考にしてもらえると良いと思います。

では、実際にコードを使ってpandasをインポートしていきましょう。
ちなみに、ファイルの用意に関してはすでに行ってあるものとして話を進めていきます。

import pandas as pd
import matplotlib.pyplot as plt

棒グラフ作成のためのmatplotlibも必須となるので、あわせてインポートしておきましょう。

今回使用するデータの説明

今回使用するデータは、Kaggleの『Japan_population_data.csv』といったcsv形式のデータセットです。

今回用いるデータセットには7つの特徴量が含まれているので、それぞれの説明を表にまとめておきます。

特徴量説明
prefecture県名
year
population人口
capital県庁所在地
region地区(関東地方、東北地方等)
estimated_area推定面積
island島(本州、四国等)

また、参考までに読み込んだデータの出力結果を以下に示しておきます。

<input>

import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv("Japan_population_data.csv")

print(data)

<output>

         prefecture       year  population     capital region  estimated_area  \
0         Aichi-ken  1872.1667   1210368.0  Nagoya-shi  Chubu         5165.12   
1         Aichi-ken  1873.0000   1217444.0  Nagoya-shi  Chubu         5165.12   
2         Aichi-ken  1874.0000   1217521.0  Nagoya-shi  Chubu         5165.12   
3         Aichi-ken  1875.0000   1234003.0  Nagoya-shi  Chubu         5165.12   
4         Aichi-ken  1876.0000   1244711.0  Nagoya-shi  Chubu         5165.12   
...             ...        ...         ...         ...    ...             ...   
2627  Yamanashi-ken  1995.7500    881996.0    Kofu-shi  Chubu         4465.37   
2628  Yamanashi-ken  2000.7500    888172.0    Kofu-shi  Chubu         4465.37   
2629  Yamanashi-ken  2005.7500    884515.0    Kofu-shi  Chubu         4465.37   
2630  Yamanashi-ken  2010.7500    863075.0    Kofu-shi  Chubu         4465.37   
2631  Yamanashi-ken  2015.7500    835165.0    Kofu-shi  Chubu         4465.37   

      island  
0     Honshu  
1     Honshu  
2     Honshu  
3     Honshu  
4     Honshu  
...      ...  
2627  Honshu  
2628  Honshu  
2629  Honshu  
2630  Honshu  
2631  Honshu  

棒グラフを用いた県ごとの人口比較(1873年)

では、早速データを使って棒グラフを作成していきましょう。
今回は、県ごとの人工比較のために棒グラフを使用したいと思います。
また、今回使用するデータセットには、1873年の人口のデータから2015年の人口のデータまであるので、それぞれの年で県ごとの人口がどのように変わったのかも確認していきましょう。

まず、1873年時の県ごとの人口比較です。

<input>

import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv("Japan_population_data.csv", index_col = 0) #ファイルからデータを読み込み
data_1873 = data.query('year == 1873') #特徴量yearが1873のものだけを抽出してdata_1873に代入

#北海道
y_Hokkaido = data_1873.at['Hokkaido', 'population'] #data_1873の中から、Hokkaidoのpopulationにある値を取得して代入
#東京都
y_Tokyo = data_1873.at['Tokyo-to', 'population']
#京都府
y_Kyoto = data_1873.at['Kyoto-fu', 'population']
#長崎県
y_Nagasaki = data_1873.at['Nagasaki-ken', 'population']
#沖縄
y_Okinawa = data_1873.at['Okinawa-ken', 'population']

x = ['Hokkaido', 'Tokyo', 'Kyoto', 'Nagasaki', 'Okinawa'] #x軸の設定
y = [y_Hokkaido, y_Tokyo, y_Kyoto, y_Nagasaki, y_Okinawa] #y軸の設定

plt.bar(x, y)
plt.title('1873') #グラフタイトルの設定
plt.show()

<output>

このような形です。
47都道府県に対して行うのは少し大変でしたので、今回は5都道府県を抽出してグラフを作成したといった感じです。
興味のある方は、47都道府県やってみるのも良いですね。そこまで時間はかからないと思います。
コード内に出てくる関数や引数の説明は簡単に下の表にまとめてあるので、コードのみだとよくわからないといった方はそちらをご覧ください。

関数・引数説明
4行目:index_col4行目では、ファイルを読み込む処理が行われているのですが、index_colは読み込む際に、見出し行(各列のタイトル)を指定するための引数です。今回は「index_col=0」となっているので0行目、つまり一番上の行がタイトルですよといった読み取り方をしていることになります。
data_1873.at[x,y]こちらは、読み込んだデータ内のある値を抽出したいときに用いる関数です。
今回は、data_1873としているので、data_1873内のx行y列目のデータを抽出するといった処理になっています。

棒グラフを用いた年ごとの人口比較

先ほどは、1873年地点での県ごとの人口比較を行いましたが、今度はその人口差が2015年にはどのくらいになっているのかを確認していこうと思います。少し古いデータなのですが、皆さんも予想しながらご覧ください。

<input>

import pandas as pd
import matplotlib.pyplot as plt

plt.figure(figsize=(15,8)) #図のサイズを決定
plt.subplots_adjust(wspace=0.2, hspace =0.6) #グラフ間の距離を設定
data = pd.read_csv("Japan_population_data.csv", index_col = 0) #データの読み込み
data_1873 = data.query('year == 1873') #特徴量yearが1873のものだけを抽出してdata_1873に代入
data_2015 = data.query('year == 2015.75') #特徴量yearが2015.75のものだけを抽出してdata_2015に代入

#ここから、1873年のグラフ作成
plt.subplot(1,2,1)
#北海道
y_Hokkaido = data_1873.at['Hokkaido', 'population'] #data_1873の中から、Hokkaidoのpopulationにある値を取得して代入
#東京都
y_Tokyo = data_1873.at['Tokyo-to', 'population']
#京都府
y_Kyoto = data_1873.at['Kyoto-fu', 'population']
#長崎県
y_Nagasaki = data_1873.at['Nagasaki-ken', 'population']
#沖縄
y_Okinawa = data_1873.at['Okinawa-ken', 'population']

x = ['Hokkaido', 'Tokyo', 'Kyoto', 'Nagasaki', 'Okinawa'] #x軸の設定
y = [y_Hokkaido, y_Tokyo, y_Kyoto, y_Nagasaki, y_Okinawa] #y軸の設定

plt.bar(x, y)
plt.title('1873') #タイトル設定

#ここから、2015年のグラフ作成
plt.subplot(1,2,2)
#北海道
y_Hokkaido = data_2015.at['Hokkaido', 'population'] #data_2015の中から、Hokkaidoのpopulationにある値を取得して代入
#東京都
y_Tokyo = data_2015.at['Tokyo-to', 'population']
#京都府
y_Kyoto = data_2015.at['Kyoto-fu', 'population']
#長崎県
y_Nagasaki = data_2015.at['Nagasaki-ken', 'population']
#沖縄
y_Okinawa = data_2015.at['Okinawa-ken', 'population']

x = ['Hokkaido', 'Tokyo', 'Kyoto', 'Nagasaki', 'Okinawa'] #x軸の設定
y = [y_Hokkaido, y_Tokyo, y_Kyoto, y_Nagasaki, y_Okinawa] #y軸の設定

plt.bar(x, y)
plt.title('2015') #タイトル設定

plt.show()

<output>

グラフを比較して言えることは、「東京人口増えすぎ!」ってことですよね。
1873年の頃は京都とほとんど同じだったのに、今や東京の人口は京都の約6倍、、
40年でここまで変わってしまうんですね。

ということで、簡単なコードの説明なのですが、基本的には見覚えがある関数が並んでいると思います。
先ほどなかった関数はすべて、グラフを二つ並べるためのものだと思ってもらえれば大丈夫です。
下の表で説明を付け加えているので、気になる方は見てみてください。

引数・関数説明
plt.figure(x,y)複数のグラフを同時に書きたいときには必須の関数です。複数グラフを置くための紙を用意する関数だと思ってもらえれば大丈夫です。
紙のサイズは、xとyで指定することが出来ます。
plt.subplots_adjustこちらも複数グラフを同時に書きたいときに使える関数で、グラフ間の距離を指定するものとなっています。
wspaceが横のグラフとの距離、hspaceが縦のグラフとの距離となっています。
plt.subplot(x,y,z)こちらも、上記二つの関数同様、複数グラフを書きたいときに使用します。
簡単に説明すると、plt.figureで作成した紙のどの位置にグラフを配置するかを指定することが出来ます。
指定方法は、x行y行列のz番目といった感じです。
それだけ聞いてぴんと来ない方も、x,y,zに好きな値を入れてみて試してみましょう。

 まとめ

今回は、基本的な棒グラフの作り方から、棒グラフの様々なカスタマイズ方法、そして実際のデータを用いたデータ解析に取り組んでいったのですが、棒グラフに対する理解は深まったでしょうか。

棒グラフは、データ同士を単純比較するときに非常に重宝するグラフです。
使い方をマスターして様々な場面に生かしていきましょう。

-Phython
-,