記事へのコメント・ご質問はこちらから。

【Python】Matplotlibでエラーバー付き複数棒グラフを作成するやり方

IT
【PR】本記事のリンクには広告が含まれています。

PythonのライブラリであるMatplotlibを使用することで、2次元のグラフを作成することができます。

今回は、Excelファイルのデータを読み込み、matplotlibでグラフ化(エラーバー付きの複数棒グラフ)する方法をご紹介します。

スポンサーリンク

実施環境

■ 使用したPC

  • ASUS Zenbook 14(UM425QA-KIR915WS)
  • OS:Windows 11 Home 64bit

スペックの詳細はこちらの記事に書いています。

■ 参考図書

Python初心者向けのテキストです。今回はこちらの2冊を参考にしました。

鈴木たかのり、降籏洋行、平井孝幸、株式会社ビープラウド

Pythonでグラフを作成する

Python(Matplotlib)でグラフを作成する流れは、以下の通りです。

  • Step 0
    JupyterLabを起動する
  • Step 1
    Excelファイルをアップロードする

  • Step 2
    データを読み込む
  • Step 3
    データを整形する
  • Step 4
    データをグラフ化する
  • Step 5
    グラフの外観を設定する

それぞれのやり方について、以下で詳しく見ていきます。

JupyterLabを起動する

前準備として、Webブラウザ上でPythonコードを実行するために「JupyterLab」を起動します。

JupyterLabの起動までの方法は、以下の記事で詳しく説明しています。

Excelファイルをアップロードする

グラフにするデータが含まれたExcelファイルを、JupyterLabを実行しているフォルダにアップロードします。

JupyterLabの左上にあるアイコンをクリックして、Excelファイルを選択します。

Excelファイルがアップロードされると、左メニューにファイル名が表示されます。

データを読み込む

pandasでアップロードしたExcelファイルのデータを読み込みます。

#グラフ描画に必要なライブラリをimportする
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#Excelファイルを読み込む
df = pd.read_excel('speedtest_data_netcafe.xlsx')
df

上のコードを実行すると、Excelファイルのデータが読み込まれ、2次元データのDataFrame(データフレーム)として出力されました。

ちなみに、今回使用するExcelファイル「speedtest_data_netcafe.xlsx」のデータは、筆者がネットカフェで計測したVPN有無によるネットワーク通信速度の比較データです。

データを整形する

Excelファイルから読み込んだデータは、グラフ描画に必要のないデータも含まれているため、扱いやすいように不要な列(カラム)の削除やデータの抽出を行います。

不要な列(カラム)を削除する

まず、1行目の「ID」の列(カラム)を削除します。

#1列目の「ID」を削除
df = df.drop('ID', axis=1)
df

1行目の「ID」のカラムが削除されました。

条件を指定してデータを抽出する

今回のデータは、次の2種類に区別することができます。

  • PCがWindows、VPNあり
  • PCがWindows、VPNなし

これらのデータが1つのテーブルとして読み込まれているので、それらを抽出して2つのDataFrameに分割します。

まず「PCがWindows、VPNあり」のデータを抽出します。

#PCがWindows、VPNありのデータを抽出
df_win_vpn = df[
                (df['pc'] == 'windows') &
                (df['vpn'] == 1)
      	       ]
df_win_vpn

同様にして、「df_win_novpn」も作成します。

#PCがWindows、VPNなしのデータを抽出
df_win_novpn = df[
                    (df['pc'] == 'windows') &
                    (df['vpn'] == 0)
                 ]

各データの抽出ができたら、「vpn」カラムを削除します。

#「vpn」カラムを削除
df_win_vpn = df_win_vpn.drop('vpn', axis=1)

df_win_novpn = df_win_novpn.drop('vpn', axis=1)

基本統計量を出力する

DataFrameごとの基本統計量(最大値、最小値、平均値など)を出力して、データの概要を確認しておきます。

#describeメソッドでDataFrameの基本統計量を出力
df_win_vpn.describe()
download_megabitsupload_megabitslatency_ms
count5.0000005.0000005.00000
mean28.84600029.52800010.80000
std6.9170549.3372871.30384
min17.61000017.61000010.00000
25%28.31000025.77000010.00000
50%29.26000026.55000010.00000
75%34.23000036.65000011.00000
max34.82000041.06000013.00000

出力された各項目の意味は、以下の通りです。

  • count:データの個数(欠損値は含まない)
  • mean:平均値
  • std:標本標準偏差
  • min:最小値
  • 25%:第1四分位数
  • 50%:中央値
  • 75%:第3四分位数
  • max;最大値

データの整形については以上です。

データをグラフ化する

ここからは、Matplotlibでデータをグラフ化していきます。

生データをそのままグラフ化したいときは、次のコードを実行します。

#棒グラフを描画する
df_win_vpn.plot.bar()

棒グラフをカラムごとに分けて表示したい場合は、次の通りです。

#カラムごとの棒グラフを描画する
df_win_vpn.plot.bar(subplots=True)

データの平均値や標準偏差を計算してグラフ化する場合は、まず各データの統計量を計算します。

#「windows、VPNあり」の平均値と標準偏差を計算
win_vpn_mean_values = df_win_vpn[['download_megabits', 'upload_megabits', 'latency_ms']].mean()
win_vpn_std_values = df_win_vpn[['download_megabits', 'upload_megabits', 'latency_ms']].std()

print(win_vpn_mean_values)
print(win_vpn_std_values)
download_megabits    28.846
upload_megabits      29.528
latency_ms           10.800
dtype: float64

download_megabits    6.917054
upload_megabits      9.337287
latency_ms           1.303840
dtype: float64

上のように計算された数値は、2次元データのDataFrameではなく、1次元データのSeries(シリーズ)と呼ばれます。

計算した結果を用いて、以下のようにグラフ化します。

#平均値の棒グラフを描画する
x = np.arange(len(win_vpn_mean_values))
width = 0.5

fig, ax = plt.subplots()
ax.bar(x, win_vpn_mean_values, width=width, align='center')
plt.ylabel('Mean Value')
plt.xticks(x, ['download_megabits', 'upload_megabits', 'latency_ms'])
plt.show()

グラフの外観を設定する

単純なグラフが作成できたら、次はグラフの外観(見た目)を設定していきます。

今回は、次の3つのやり方についてご紹介します。

  • 複数の棒グラフを並べる
  • エラーバーを付ける
  • 目盛りを内側にする

複数の棒グラフを並べる

以下のように書くと、複数の棒グラフを並べて描画できます。

#複数の棒グラフを描画する
x = np.arange(len(win_vpn_mean_values))
width = 0.3

fig, ax = plt.subplots()
ax.bar(x, win_vpn_mean_values, width=width, label='win_vpn', align='center')
ax.bar(x+width, win_novpn_mean_values, width=width, label='win_novpn', align='center')
ax.bar(x+width*2, mac_novpn_mean_values, width=width, label='mac_novpn', align='center')
ax.legend()

plt.ylabel('Mean Value')
plt.xticks(x+width*2/2, ['download_megabits', 'upload_megabits', 'latency_ms'])
plt.show()

エラーバーをつける

以下のように書くと、エラーバー付き棒グラフを描画できます。

#エラーバー付き棒グラフを描画する
x = np.arange(len(win_vpn_mean_values))
width = 0.6

fig, ax = plt.subplots()
ax.bar(x, win_vpn_mean_values, yerr=win_vpn_std_values, width=width, align='center', ecolor='black', capsize=5)
plt.ylabel('Mean Value')
plt.xticks(x, ['download_megabits', 'upload_megabits', 'latency_ms'])
plt.show()
パラメータ意味
x棒グラフのX軸方向の位置(配列)
win_vpn_mean_values棒グラフのY軸方向の値(配列)
yerrエラーバー(標準偏差)の値(配列)
width棒グラフの幅
alignX軸の目盛の位置
ecolorエラーバーの色
capsizeエラーバーの横線の長さ
plt.bar()のパラメータの説明

複数種類の棒グラフにエラーバーを付けるには、次のように書きます。

#エラーバー付きの複数の棒グラフを描画する
x = np.arange(len(win_vpn_mean_values))
width = 0.3

fig, ax = plt.subplots()
ax.bar(x, win_vpn_mean_values,  yerr=win_vpn_std_values, width=width, label='win_vpn', align='center', ecolor='black', capsize=5)
ax.bar(x+width, win_novpn_mean_values,  yerr=win_novpn_std_values, width=width, label='win_novpn', align='center', ecolor='black', capsize=5)
ax.legend()

plt.ylabel('Mean Value')
plt.xticks(x+width/2, ['download_megabits', 'upload_megabits', 'latency_ms'])
plt.show()

目盛りを内側にする

グラフの目盛りを内側にするには、以下のように設定します。

#目盛りを内側にしたエラーバー付きの複数の棒グラフを描画する
x = np.arange(len(win_vpn_mean_values))
width = 0.3

fig, ax = plt.subplots()
ax.bar(x, win_vpn_mean_values,  yerr=win_vpn_std_values, width=width, label='win_vpn', align='center', ecolor='black', capsize=5)
ax.bar(x+width, win_novpn_mean_values,  yerr=win_novpn_std_values, width=width, label='win_novpn', align='center', ecolor='black', capsize=5)
ax.legend()

plt.ylabel('Mean Value')
plt.xticks(x+width/2, ['download_megabits', 'upload_megabits', 'latency_ms'])

#X軸とY軸の目盛を内側にする
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'

plt.show()

参考
神戸学院大学 経営学部 林坂ゼミ | Matplotlib
matplotlib エラーバー付きのグラフを描く #Python – Qiita
python:matplotlib:目盛りの設定 [雑多な記録]

まとめ

以上、Excelファイルのデータを読み込み、matplotlibでグラフ化(エラーバー付きの複数棒グラフ)する方法をご紹介しました。

今回参考にした『Pythonによるあたらしいデータ分析の教科書 第2版』では、Python初心者に向けて環境設定のやり方やデータ分析の方法が分かりやすく書かれています。

よければ参考に覗いてみてください。

えのきつね
えのきつね

最後まで読んでくださり、ありがとうございました!