見出し画像

プログラミング系科目オール「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話公開。

この記事が気に入ったらサポートをしてみませんか?