プログラミング系科目オール「C」の俺がPythonに一目惚れして局所天気図の描写に挑む話 ~第2話~
あらすじ
大学の必修科目であるプログラミング(C言語)を機にプログラミングに嫌悪感を抱くようになったうえはーす。とある講義にて扱ったPythonに一目惚れし、局地天気図の描写に挑むことを決意する。一度は描けた天気図であったが、納得のいかない出来にコードの見直しを始める。観測点のプロットまでは問題なく再現できたが、観測点名の表示の際に躓いたことを思い出すのであった。
テキストが地図に描写されない
話は少し前に遡る。初めてCSVファイルから読み込んだ観測点名を地図に映そうとしたときのことだ。
~~~~~~~~~~
無知な俺「df['lon']、df['lat']で緯度・経度データを抜き出してくれるってことは……観測点の地名を出すにはこうすればいいんでしょ」
print(df['site'])
----------
0 Irako
1 Nagoya
2 Gifu
3 Takayama
4 Yokkaichi
5 Tsu
6 Owase
7 Ueno
8 Hikone
9 Fukui
10 Kanazawa
11 Wajima
12 Toyama
13 Fushiki
14 Takada
15 Niigata
16 Nagano
17 Matsumoto
18 Suwa
19 Iida
20 Hamamatsu
21 Omaesaki
22 Shizuoka
23 Mishima
24 Ishirouzaki
25 Aziro
26 Maebashi
27 Koufu
28 Yokohama
29 Utsunomiya
30 Chichibu
31 Kumagaya
32 Tokyo
33 Oshima
34 Miyakejima
35 Tateyama
36 Wakamatsu
Name: site, dtype: object
無知な俺「ビンゴ! あとはこれをマーカーを表示した時と同じように、緯度・経度データと結び付けて……」
ax.text(lon, lat, df['site'], ha='center', va='top', color='navy', fontweight='heavy', fontsize='small', zorder=7)
----------
# 何も描写されない白画面のウィンドウと一緒に以下のエラーメッセージが出た
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
無知な俺「??????????(宇宙猫)」
~~~~~~~~~~
Pythonの知識が皆無に等しいこの時の俺はエラーコードの読み方すらわからなかったので非常に困った。今は何が起きたのかがある程度わかってきたので少し述べておきたい。
まず「matplotlib.axes.Axes.text」の使い方について確認してみる。
マニュアルによると「x, yには浮動小数点(float)型を、sには文字(str)型でデータを寄越しやがれ」ということらしい。
ということで過ちを犯した時のデータ型を確認してみる。
print(type(lon)) # lon = df['lon']
print(type(lat)) # lat = df['lat']
print(type(df['site']))
----------
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>
……なんということだ、Python側からしてみれば「ハンバーガー2個とコーラをくれ」と言ってるのにサラダとサラダとサラダを渡されたようなものだったのか。(何か違う)
ということで、きちんと緯度経度データはfloat型で、観測点名はstr型で受け取ってくれるように改造したコードは次の通り。ただ、まだまだ未熟者のやり方なのでより効率の良い処理法を存じている方々がいらっしゃればご教示願いたい。
for i in range(len(df)):
ax.text(df.iloc[i]['lon'], df.iloc[i]['lat'], df.iloc[i]['site'],
ha='center', va='top', color='navy', fontweight='heavy', fontsize='small', zorder=7)
# テキストの表示方法を指示する箇所は改行
for i in range(len(df))
データフレームの要素数(CSVファイルにおける行数)だけ、以下の作業を繰り返すように指示。ここでは「len(df) = 37」であるが、見出しの行は含んでいない点に留意。df.iloc[i]['lon']、df.iloc[i]['lat']、df.iloc[i]['site']
lon/lat/siteの列のi行目のデータを取り出す。一応データ型を確認してみるが、いずれもmatplotlib.axes.Axes.textで対応できる型で取り出せている。
print(df.iloc[0]['lon'], type(df.iloc[0]['lon']))
print(df.iloc[0]['lat'], type(df.iloc[0]['lat']))
print(df.iloc[0]['site'], type(df.iloc[0]['site']))
------------
137.0933333 <class 'numpy.float64'>
34.62833333 <class 'numpy.float64'>
Irako <class 'str'> # 伊良湖岬だと「いら"ご"」なのに観測点や給糧艦だと「いら"こ"」なの不思議やね。
plt.show()で表示してやるとこんな図が得られる。
いよいよ等圧線の表示に挑みたいところだが、思いの外長ったらしくなってしまったし、等圧線についての話はもっと長くなりそうなのでここで一回区切る。第3話乞うご期待。2か月弱越しに第3話公開。
この記事が気に入ったらサポートをしてみませんか?