Pythonで血圧データをグラフ化した話(ExcelからPandasでデータを読み込みMatplotlibでグラフを作成する方法)

2021年6月19日

今日は、ExcelからPandasでデータを読み込み、Matplotlibでグラフを作成する方法を説明します。

この記事で分かること

1.ExcelからPandasでデータを読み込む方法
2.PandasのデータからMatplotlibでグラフを作成する方法
3.作成したグラフを保存する方法

ExcelからPandasでデータを読み込む方法

以下のエクセルデータを見てください。本データは私の最近の血圧値です。

表の内容を説明します。

表の一番左端の列は血圧の測定日です。一番上にdataと書かれています。

次の列は血圧の上の値(SBP_Morning)です。

SBP とは、Systolic Blood Pressure(収縮期血圧)の略称です。

また、Morning は朝 測定したことを表しています。

次の列は血圧の下の値(DBP_Morning)です。

DBP とは、Diastolic Blood Pressure(拡張期血圧)の略称です。

次の列は夜の血圧の上の値(SBP_Night)です。

その次の列は夜の血圧の下の値(DBP_Night)です。

最後の2列は、薬を飲む前の血圧の上と下の値(SBP_before、DBP_before)です。

薬を飲む前後で血圧値がどう変化したかが分かるように比較値としています。

ソースコード

では、実際にExcelファイルからPandasでデータを読み込んでみます。

以下のソースコードを見てください。

import pandas as pd
# エクセルファイルが置いてあるフォルダのパス
path = './test_photo/hana/plot/blood_pressure_2020.xlsx'
# pandasを使用してエクセルデータを読み込む
# なお、sheet_nameで読み込みたいシートを指定できる
df_1 = pd.read_excel(path, sheet_name='data_all') 
# loc[行、列]でデータ読み込み。
x0 = df_1.loc[:, 'data']          # 全行の'data'列の値を読み込む
y0 = df_1.loc[:, 'SBP_Morning']
y1 = df_1.loc[:, 'DBP_Morning']
y2 = df_1.loc[:, 'SBP_Night']
y3 = df_1.loc[:, 'DBP_Night']
y4 = df_1.loc[:, 'SBP_before']
y5 = df_1.loc[:, 'DBP_before']
# 読み込んだデータの確認
print(df_1)
print(x0)

Excelファイルのデータ読み込みにはPandasを使用するので、もしPandasをインストールしていない場合は、コマンドプロンプトからpipでインストールしてください。

> pip install pandas  ⏎

以下は、Pandasがインストールされていることを前提に説明します。

はじめに、Pandasをインポートしてください。

import pandas as pd

次に、Excelファイルが置いてあるフォルダのパスを指定します。

path = './test_photo/hana/plot/blood_pressure_2020.xlsx'

Excelファイルから読み込む際にシートを指定できます。

今回は、data_all というシートからデータを読み込みます。

df_1 = pd.read_excel(path, sheet_name='data_all') 

Excelファイルの data_allシートからデータが読み込まれ df_1 に値が代入されます。

df_1に値が代入されたか確認するには、print( ) を使用します。

print(df_1)

なお、data 列だけ読み込みたい場合は、loc[ ] を使用します。loc[ 行、列 ]の順でデータを指定します。

x0 = df_1.loc[:, 'data']

上記コードの意味は、data列の全ての行のデータを読み込んで x0 に代入しなさいという指示になります。

確認するには、print( ) を使用します。

print(x0)

ポイント

  • Excelの一番上の行をキーにすることができます。
  • loc[ ] を使用すれば、キーを利用して必要な列データを読み込むことができます。

グラフ作成時のことを考えると、各列ごとにデータを読み込んで、各変数に代入しておく方が便利です。

PandasのデータからMatplotlibでグラフを作成する方法

以下のソースコードを見てください。

import seaborn
import numpy as np
import pandas as pd
import matplotlib.style
import matplotlib.pyplot as plt
# グラフのスタイル指定
lists = ['bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight',
         'ggplot', 'grayscale', 'seaborn-bright', 'seaborn-colorblind',
         'seaborn-dark-palette', 'seaborn-dark', 'seaborn-darkgrid',
         'seaborn-deep', 'seaborn-muted', 'seaborn-notebook',
         'seaborn-paper', 'seaborn-pastel', 'seaborn-poster',
         'seaborn-talk', 'seaborn-ticks', 'seaborn-white',
         'seaborn-whitegrid', 'seaborn', 'Solarize_Light2',
         'tableau-colorblind10', '_classic_test']
plt.style.use(lists[5])
# グラフ作成
fig, ax = plt.subplots(figsize=(18, 10))
# styleを指定
style = dict(size=15, color='gray')
# ax.text()メソッドを使用してグラフに文字を描画
# なお上記で指定したstyleを**styleで呼ぶ
ax.text('2020.04.28', 185, "SBP_before", **style)
ax.text('2020.04.28', 110, "DBP_before", **style)
# ax.set()メソッドを使用して全てのプロパティを同時に設定
ax.set(ylim=(0, 200),
       xlabel='Measuring Data',
       ylabel='Blood Pressure(mmHg)',
       title='Trend Data',
       xticks=(np.arange(0, 54, 7))
       )
# 各ラベルのサイズを変更したいとき
ax.set_xlabel('Measuring Data', size=15)
ax.set_ylabel('Blood Pressure(mmHg)', size=15)
ax.set_title('Trend Data', size=20)
# グラフに注釈(文字と矢印)を描画
ax.annotate('chenge medicine',
            xy=('2020.04.01', 94),
            xycoords='data',
            xytext=(50, -50),
            size=15,
            textcoords='offset points',
            ha='center',
            arrowprops=dict(facecolor='black', shrink=0.05))
ax.annotate('chenge medicine',
            xy=('2020.04.01', 156),
            xycoords='data',
            xytext=(50, 40),
            size=15,
            textcoords='offset points',
            ha='center',
            arrowprops=dict(arrowstyle="fancy", 
                            connectionstyle="angle3, angleA=0, angleB=-90",
                            color='black'))
# グラフを描画
ax.plot(x0, y0, 'bo-', linewidth=3, markersize=10, label='SBP_Morning')
ax.plot(x0, y2, 'rp-', linewidth=3, markersize=10, label='SBP_Night')
ax.plot(x0, y1, 'gh-', linewidth=3, markersize=10, label='DBP_Morning')
ax.plot(x0, y3, 'cs-', linewidth=3, markersize=10, label='DBP_Night')
ax.plot(x0, y4, 'm-', linewidth=3, markersize=10, label='SBP_before')
ax.plot(x0, y5, 'y-', linewidth=3, markersize=10, label='NBP_before')
# 凡例を表示
ax.legend(fontsize=15)
# グラフを保存
fig.savefig('./test_photo/hana/plot/results.png')
plt.show()

ソースコードを順に説明します。

Matplotlibのスタイルシートの設定

2014年8月にリリースされたMatplotlibのバージョン1.4で、styleモジュールが追加されました。

これにより、目的に応じてグラフの見栄えを変えることができます。

デフォルトで利用可能なスタイルを、コードにまとめて記載しておきました。

グラフのスタイル指定は以下のコードで行います。

plt.style.use(lists[5])

上記コードは、lists = [ ] の中の 5番目を指定しています。つまり、’ggplot’ です。

[ ] の中は 0番からカウントするので、0番目は 'bmh’ です。

ちなみに、ggplot パッケージは R言語の可視化ツールです。とても見やすいグラフが作成でき人気があります。Matplotlib の ggplot スタイルは、そのデフォルトスタイルを模倣しています。

グラフスタイルを決め打ちで指定するなら、以下のように記載すれば良いです。

plt.style.use('ggplot')

今回は参考のために、色々なスタイルを記載しました。もし興味があれば色々変えてみてください。

グラフに描画する文字の設定

以下のソースコードを見てください。

# styleを指定
style = dict(size=15, color='gray')
# ax.text()メソッドを使用してグラフに文字を描画
# なお上記で指定したstyleを**styleで呼ぶ
ax.text('2020.04.28', 185, "SBP_before", **style)
ax.text('2020.04.28', 110, "DBP_before", **style)

ax.text( ) メソッドを使用すると、グラフに描画する文字を設定することができます。

ax.text( ' 2020.04.28 ' , 185, " SBP_before " , **style ) を例に、カッコの中身を説明します。

第一引数は、x軸の値( '2020.04.28’ )を指します。

第二引数は、y軸の値(185)を指します。

第三引数は、グラフに描画する文字を指します。

第四引数は、描画する文字のスタイル(文字サイズ、色)を指定します。

なお、文字に適用するスタイルが共通な場合は 先にstyle = dict( ) として、指定する値を決めておきます。

ax.text( ) の第四引数として「** style」と記載しておくことで、先に指定したstyle = dict( ) のカッコ中のキーワード引数( size=15 と color=’gray’ )を渡すことができます。

グラフの軸、ラベル、タイトルの設定

以下のソースコードを見てください。

# ax.set()メソッドを使用して全てのプロパティを同時に設定
ax.set(ylim=(0, 200),
       xlabel='Measuring Data',
       ylabel='Blood Pressure(mmHg)',
       title='Trend Data',
       xticks=(np.arange(0, 54, 7))
       )
# 各ラベルのサイズを変更したいとき
ax.set_xlabel('Measuring Data', size=15)
ax.set_ylabel('Blood Pressure(mmHg)', size=15)
ax.set_title('Trend Data', size=20)

ax.set( ) メソッドを使うと全てのプロパティを同時に設定することができます。

カッコの中身を説明します。

第一引数は、y軸の範囲です。0 ~ 200の範囲としています。

第二引数は、x軸のラベルです。

第三引数は、y軸のラベルです。

第四引数は、グラフのタイトルです。

第五引数は、x軸の範囲です。ちょっとした技を使っているので説明します。

xticks=(np.arange(0, 54, 7))

コードの意味を説明します。

np.arange( 0, 54, 7 ) はNumPy のarange 関数を使って、0から54まであるデータを7個飛ばしでプロットしなさいという意味です。7にした理由は1週間の血圧変動を知るためです。また、わざわざ np.arange( ) 関数を使った理由は、x軸のデータは Excel の data 列の値なので日付データとなっています。単純な数字ではないため、データを個数と考えて、54個のデータを何個おきにプロットするかという観点で考えたため、np.arange( ) 関数を使っています。

次に、ax.set( ) メソッドを使うと全てのプロパティを同時に設定することができて便利ですが、ラベルやタイトルのサイズを微調整したいときに、不便な場合があります。

そんなときは、以下のように個々に設定した方が良い場合もあります。

# 各ラベルのサイズを変更したいとき
ax.set_xlabel('Measuring Data', size=15)
ax.set_ylabel('Blood Pressure(mmHg)', size=15)
ax.set_title('Trend Data', size=20)

グラフの見栄えによって、便利な方を使用してください。

グラフに注釈(文字と矢印)を描画

以下のソースコードを見てください。

# グラフに注釈(文字と矢印)を描画
ax.annotate('chenge medicine',
            xy=('2020.04.01', 94),
            xycoords='data',
            xytext=(50, -50),
            size=15,
            textcoords='offset points',
            ha='center',
            arrowprops=dict(facecolor='black', shrink=0.05))
ax.annotate('chenge medicine',
            xy=('2020.04.01', 156),
            xycoords='data',
            xytext=(50, 40),
            size=15,
            textcoords='offset points',
            ha='center',
            arrowprops=dict(arrowstyle="fancy", 
                            connectionstyle="angle3, angleA=0, angleB=-90",
                            color='black'))

参考に2パターン示します。なお、コードの意味は共通であるため、最初のコードについて説明します。

グラフに注釈を描画するには、ax.annotate( ) を使用します。

第一引数は、描画する文字です。

第二引数は、矢印が指し示す場所の座標(x, y)です。

第三引数は、注釈が付けられているオブジェクトの座標系を使用することを宣言したものです。デフォルトは、data です。

第四引数は、文字(テキスト)の座標です。

第五引数は、文字サイズです。

第六引数は、ポイント値で文字(テキスト)をオフセットすることを示しています。

第七引数は、文字が水平整列(horizontal alignment)するよう指定しています。

第八引数は、描画する矢印 の「色」と「両端から縮む全長の割合」を指定しています。

なお、詳細はMatplotlibの「matplotlib.axes.Axes.annotate」ページを参照ください。

グラフの描画

以下のソースコードを見てください。

# グラフを描画
ax.plot(x0, y0, 'bo-', linewidth=3, markersize=10, label='SBP_Morning')
ax.plot(x0, y2, 'rp-', linewidth=3, markersize=10, label='SBP_Night')
ax.plot(x0, y1, 'gh-', linewidth=3, markersize=10, label='DBP_Morning')
ax.plot(x0, y3, 'cs-', linewidth=3, markersize=10, label='DBP_Night')
ax.plot(x0, y4, 'm-', linewidth=3, markersize=10, label='SBP_before')
ax.plot(x0, y5, 'y-', linewidth=3, markersize=10, label='NBP_before')

グラフを描画するには、ax.plot( ) を使用します。

カッコの中身を説明します。

第一、第二引数は、xとyの値です。

第三引数は、 '「色」「マーカースタイル」「ライン」’ の順番で指示しています。

以下に各記号を示します。これ以外にも色々な記号があります。

詳細はMatplotlibの「matplotlib.axes.Axes.plot」ページを参照ください。

character(記号)color(色)
' b 'blue(青)
' g 'green(緑)
' r 'red(赤)
' c 'cyan(水色)
' m 'magenta(赤紫色)
' y 'yellow(黄色)
' k 'black(黒)
' w 'white(白)
色の記号
character(記号)description(解説)
' o 'circle marker(丸マーカー)
' p 'pentagon marker(五角形マーカー)
' h 'hexagon1 marker(六角形マーカー)
' s 'square marker(四角マーカー)
マーカーの記号
character(記号)description(解説)
' – 'solid line style(直線)
ラインの記号

第四引数は、線の幅(太さ)を指定しています。

第五引数は、マーカーサイズを指定しています。

第六引数は、凡例にするラベル名を指定しています。

なお上記コードの二行目と三行目はわざと入れ替えています。理由は、凡例を表示させる際にSBPのMorning と Night を並べ、次にDBPのMorning と Night を並べて表示させた方が見やすくなるからです。

凡例の描画

以下のソースコードを見てください。

# 凡例を表示
ax.legend(fontsize=15)

凡例は、ax.legend( ) で指定します。なお、fontsize で凡例のサイズが変更できます。

作成したグラフを保存する方法

以下のソースコードを見てください。

# グラフを保存
fig.savefig('./test_photo/hana/plot/results.png')

最後に、fig.savefig( ) でグラフを保存します。

カッコの中身は、グラフ保存先のフォルダを指定します。

拡張子は、png に限らず jpg でも良いです。

まとめ

  • PandasでExcelファイルからデータを読み込む際にシートを指定できる
  • Excelの一番上の行をキーにすることができる
  • loc[ ] を使用すれば、キーを利用して必要な列データを読み込むことができる
  • plt.style.use( ) を使用するとグラフのスタイルを変更できる
  • ax.text( ) を使用するとグラフに描画する文字を設定できる
  • ax.set( ) を使用するとグラフの全てのプロパティを同時に設定することができる
  • ax.annotate( ) を使用するとグラフに注釈を描画することができる
  • ax.plot( ) を使用するとグラフが描画できる
  • ax.legend( ) を使用すると凡例が表示できる
  • fig.savefig( ) を使用するとグラフが保存できる

あとがき

今回は血圧データをグラフ化してみました。

はじめて飲んだ薬は「アムロジピン錠 5mg」でした。これを、2020年3月17日から3月31日まで飲んでいました。グラフから、この期間は下の血圧があまり下がっていないことが分かります。

4月1日からは薬を変えています。次に飲んだ薬は「イルベサルタン・アムロジピン 5mg」です。先に飲んでいた薬の成分に別な成分がプラスされました。薬の個数は1錠で前と同じです。グラフから、4月1日以降は血圧の上も下も低下傾向にあることが分かります。

また、薬を飲む前の値(血圧上:180mmHg、血圧下:120mmHg)と比べ、薬を飲んでからはかなり血圧が下がっていることが分かります。

薬の効果は絶大です。体調もかなり良くなりました。もう頭痛、吐き気はありません。

同じ悩みがある方は早めに病院に行くことをおすすめします。

今回グラフ化したことで血圧のトレンドがかなり分かり易くなりました。

血圧に限らず体重管理にも使えそうです。

エクセルより一味も二味も違うグラフが作成できます。

そんなグラフを作成してみたいと思っている方は、一度試してみてはいかがでしょうか。

プログラムの勉強にもなるし、かなりおすすめです。

参考図書