Python:Matplotlibでグラフの作成(Google Colaboratory)
秋田県の豪雨で友人が床上浸水となりました.国土交通省の「川の防災情報」というサイトで河川の水位と雨量を公開していましたので,何があったのか,可視化してみました.
![](https://assets.st-note.com/img/1689720560287-BdlBZwhAji.png?width=800)
このサイトはAPIが有料のようで,公開されているのは2日分くらいです.
![](https://assets.st-note.com/img/1689720742194-BYI2QSkcZU.png)
Excelにコピペすると水位の矢印が2段になってたり,上が新しい時刻だったり,そこはVBAで形式を以下のように整えました.
![](https://assets.st-note.com/img/1689720950906-7gJCd1LUj3.png?width=800)
ここから随時データを取得して追加して,そのたびにグラフを描いていましたので,Excelでは毎回の操作がとても面倒です.
Pythonなら,プログラムを実行すればよいので,グラフの描き直しがとても楽にできました.
以下の項目をプログラムにしました.
上部にはデータソースや場所の情報を置いておきたかったが,7行目まではDataFrameに読み込みたくない.
上部の記述の分も列に含んでしまうので,F列より右は削除
「欠測」のある行は削除
「欠測」のため,時間雨量は文字列になってしまっており,数値に変換する必要がある.
雨量をグラフで,水位を折れ線グラフにしたい.
水位を第2軸にしたい(本当は水位を第1軸にしたいのだけれど,折れ線グラフを前に表示するために後から表示するため)
氾濫危険水位(8.1m)と氾濫注意水位(6.3m)を明示したい.
強い雨の目安(10mm)を明示したい.
凡例を表示
横軸ラベルが重ならないように
グラフ内にコメントを入れたい
.(1)グラフに日本語を表示させるためのライブラリをインストール
Colaboratoryは,Googleのサーバ上の仮想環境なので,毎回インストール作業が必要
!pip install japanize_matplotlib
Successfullyと表示されれば,インストール成功です.
(2)データの読み込み
ファイルは,UTF-08CSV形式で保存
上部のメモの部分を避けて読み込む.
import pandas as pd
df = pd.read_csv("/content/秋田豪雨20230716Python.csv" , skiprows=list(range(7)))
df.head()
![](https://assets.st-note.com/img/1689722469667-ZS6sBt6sWD.png?width=800)
skiprowsには読み込みをスキップする行数をリストで記述します.
例)
skiprows=[1,2,3]
1行目と2行目と3行目をスキップする.
ここでは、1行目から7行目まで全部スキップするので,rangeで数値列を生成し,これをリストに変換しています.
(3)DataFarmeの不要部分の削除
df = df.drop('Unnamed: 5', axis=1)
df = df.drop('Unnamed: 6', axis=1)
df = df.drop('Unnamed: 7', axis=1)
df = df.drop('Unnamed: 8', axis=1)
df = df[~df['時間雨量[mm]'].str.contains('欠測')]
df.head()
![](https://assets.st-note.com/img/1689722596956-nkYulxlXdh.png?width=800)
dropで列を削除します.ここでは列名を指定して削除しました.
列方向の削除なので「axis=1」を記述します.
時間雨量の列に「欠測」を含む行を削除します.
df['時間雨量[mm]'].str.contains('欠測')
は,この列の各行の全部について文字列処理をするというアクセサstrに続き, Stringのメソッドcontainsで「欠測」という文字列があるかどうか判定しています.文字列を含むときはTrueになります.
ここではFalseの行を残したいので,論理否定「~」で結果を反転させ,含まない行が残ります.
(4)文字列を日付と数値に変換
日付と時刻は文字列であり,これを2つ合わせて日付型に変換します.
雨量は「欠測」があったため,列全体が文字列になってしまっており,数値に変換します.
X_dt = pd.to_datetime(df['日付'] + " " +df['時刻'])
df['DateTime'] = X_dt
df['rain'] = pd.to_numeric(df['時間雨量[mm]'],errors='coerce')
df.head()
![](https://assets.st-note.com/img/1689723305364-Y8BROu6aJ2.png?width=800)
日付と時刻は文字列なので、文字列の加算をし,(間に半角空白が1文字ないとエラーになってしまい,それも追加)これを日付型に変換します.
(5)氾濫注意水位以上のDataFrameをとりだす
注意水位以上の部分を色を変えて表示するため,その部分を抜き出します.
limit1 = 8.1
limit2 = 6.6
limit_rain = 10
X_dt_str =df['DateTime'] .dt.strftime('%m/%d %H時')
df_red = df[df['水位[m]'] >= limit2]
limit1 : 氾濫危険水位
limit2 : 氾濫注意水位
limit_rain : これ以上は強い雨
(6)グラフを描く
それではグラフを描きましょう.
import matplotlib.pyplot as plt
import japanize_matplotlib
fig , ax = plt.subplots(figsize=(8,4))
ax2 = ax.twinx()
ax.bar(df['DateTime'] , df['rain'] , color='blue' , label='降水量(mm)' , width=0.03)
ax2.plot(df['DateTime'] , df['水位[m]'] , c='green' , label='安全な水位(m)')
ax2.plot(df_red['DateTime'] , df_red['水位[m]'] , c='red', label='危険な水位(m)')
ax2.hlines([limit1 , limit2] , X_dt[1] , X_dt[len(X_dt)-1] , colors=['red' , 'green'] ,linestyle='dashed')
ax.hlines([limit_rain] , X_dt[1] , X_dt[len(X_dt)-1] , colors=['blue'] ,linestyle='dotted')
ax.set_xticks([X_dt[i] for i in range(1,len(X_dt),24)] ,
[X_dt_str[i] for i in range(1,len(X_dt),24)])
ax.set_title('雄物川水系椿川(秋田県)の水位と降雨量')
ax.set_ylabel('1時間あたりの降水量(mm)')
ax2.set_ylabel('水位(m)')
line1 , label1 = ax.get_legend_handles_labels()
line2 , label2 = ax2.get_legend_handles_labels()
plt.legend(handles=line1+line2 , labels=label1+label2)
ax.text(df.iloc[45]['DateTime'], 10.3, "これ以上は強い雨")
ax2.text(df.iloc[1]['DateTime'], 6.7, "氾濫注意水位")
ax2.text(df.iloc[1]['DateTime'], 8.2, "氾濫危険水位")
ax2.text(df.iloc[68]['DateTime'], 4, "また強い雨が降って\n水位が上昇傾向\nこれ以上降らないで!")
plt.show()
ax2 = ax.twinx()
x軸を共通にしたax2を生成する.これで第2軸の指定ができます.
第2軸にしたときは,凡例がそれぞれになってしまうので,ラベルとハンドラを取り出して合わせて表示します.
line1 , label1 = ax.get_legend_handles_labels()
line2 , label2 = ax2.get_legend_handles_labels()
plt.legend(handles=line1+line2 , labels=label1+label2)
line1 , line2 , label1 , label2はそれぞれリストなので、加算すると,要素をくっつけることができます.
label2には「危険な水位」と「安全な水位」という2つの要素が含まれているので,凡例は全部で3つになります.
グラフ中に記入する文字列はx軸・y軸の値で位置を指定します.
![](https://assets.st-note.com/img/1689724355893-1xF1OTr22Z.png?width=800)
また雨が降って,じわじわと水位が上がってきています.
秋田の皆様,どうかご無事で