新幹線の歴史をPython (pandas, folium, PyQtなど)で可視化しながら学ぶ

# はじめに

今まで日本で色んなところに行って、鉄道について色々興味を持ってきて色々勉強しています。最近は歴史まで覚えようとしています。

特に新幹線は本当に凄いものです。1964年から始まって既に60年も経っています。意外と歴史が長くて、あんな時代からこんなものがあったなんてあまり信じられなかったです。

最初の開業からどんどん路線と駅が増えて伸びてきて、今でもまだ続いていくようです。だからどの駅がいつからできたか気になって調べてみました。

覚えやすいようにPythonでデータを整理して地図を描きながら可視化してみました。

この記事では実装のコードと結果を載せながら簡単に解説します。

# 使うデータ

駅のデータを全部持っているサイトは見つからないので、色んなサイトから集めて手動で編集しました。2025年現在新幹線駅の数は120です。

駅名や緯度経度や開業時間など必要なデータをcsvファイルに纏めています。
```csvs:eki.csv
駅名,読み方,前の駅,緯度,経度,県,開業
東京,とうきょう,,35.681391,139.766103,東京都,1964-10-01
品川,しながわ,東京,35.62876,139.738999,東京都,1964-10-01
新横浜,しんよこはま,品川,35.506824,139.617348,神奈川県,1964-10-01
小田原,おだわら,新横浜,35.256225,139.155772,神奈川県,1964-10-01
熱海,あたみ,小田原,35.103573,139.077679,静岡県,1964-10-01
三島,みしま,熱海,35.126253,138.911133,静岡県,1964-10-01
新富士,しんふじ,三島,35.142365,138.663199,静岡県,1988-03-13
静岡,しずおか,新富士,34.971629,138.388579,静岡県,1964-10-01
掛川,かけがわ,静岡,34.769463,138.014937,静岡県,1988-03-13
浜松,はままつ,掛川,34.703866,137.734759,静岡県,1964-10-01
豊橋,とよはし,浜松,34.762734,137.382128,愛知県,1964-10-01
三河安城,みかわあんじょう,豊橋,34.96968,137.060918,愛知県,1988-03-13
名古屋,なごや,三河安城,35.170694,136.881637,愛知県,1964-10-01
岐阜羽島,ぎふはしま,名古屋,35.315705,136.685593,岐阜県,1964-10-01
米原,まいばら,岐阜羽島,35.314657,136.289992,滋賀県,1964-10-01
京都,きょうと,米原,34.985465,135.757748,京都府,1964-10-01
新大阪,しんおおさか,京都,34.734136,135.501852,大阪府,1964-10-01
新神戸,しんこうべ,新大阪,34.706417,135.195758,兵庫県,1972-03-15
西明石,にしあかし,新神戸,34.66591,134.960151,兵庫県,1972-03-15
姫路,ひめじ,西明石,34.827659,134.690769,兵庫県,1972-03-15
相生,あいおい,姫路,34.818052,134.47341,兵庫県,1972-03-15
岡山,おかやま,相生,34.666572,133.918552,岡山県,1972-03-15
新倉敷,しんくらしき,岡山,34.56509,133.678344,岡山県,1975-03-10
福山,ふくやま,新倉敷,34.489291,133.361429,広島県,1975-03-10
新尾道,しんおのみち,福山,34.429859,133.190158,広島県,1988-03-13
三原,みはら,新尾道,34.400486,133.083049,広島県,1975-03-10
東広島,ひがしひろしま,三原,34.389035,132.759762,広島県,1988-03-13
広島,ひろしま,東広島,34.397446,132.475593,広島県,1975-03-10
新岩国,しんいわくに,広島,34.164672,132.149384,山口県,1975-03-10
徳山,とくやま,新岩国,34.051555,131.8029,山口県,1975-03-10
新山口,しんやまぐち,徳山,34.093255,131.39657,山口県,1975-03-10
厚狭,あさ,新山口,34.053361,131.159965,山口県,1999-03-13
新下関,しんしものせき,厚狭,34.005651,130.948021,山口県,1975-03-10
小倉,こくら,新下関,33.886756,130.882678,福岡県,1975-03-10
博多,はかた,小倉,33.590002,130.420622,福岡県,1975-03-10
博多南,はかたみなみ,博多,33.517955,130.436997,福岡県,1990-04-01
新鳥栖,しんとす,博多南,33.370278,130.491111,佐賀県,2011-03-12
久留米,くるめ,新鳥栖,33.319778,130.501408,福岡県,2011-03-12
筑後船小屋,ちくごふなごや,久留米,33.17802333,130.4916036,福岡県,2011-03-12
新大牟田,しんおおむた,筑後船小屋,33.071123,130.488786,福岡県,2011-03-12
新玉名,しんたまな,新大牟田,32.942525,130.573506,熊本県,2011-03-12
熊本,くまもと,新玉名,32.789207,130.688499,熊本県,2011-03-12
新八代,しんやつしろ,熊本,32.517888,130.634919,熊本県,2004-03-13
新水俣,しんみなまた,新八代,32.210825,130.428893,熊本県,2004-03-13
出水,いずみ,新水俣,32.089275,130.357803,鹿児島県,2004-03-13
川内,せんだい,出水,31.813726,130.31213,鹿児島県,2004-03-13
鹿児島中央,かごしまちゅうおう,川内,31.583727,130.541789,鹿児島県,2004-03-13
武雄温泉,たけおおんせん,,33.196151,130.022322,佐賀県,2022-09-23
嬉野温泉,うれしのおんせん,武雄温泉,33.106556,129.998972,佐賀県,2022-09-23
新大村,しんおおむら,嬉野温泉,32.932778,129.956944,長崎県,2022-09-23
諫早,いさはや,新大村,32.851018,130.041596,長崎県,2022-09-23
長崎,ながさき,諫早,32.75275,129.869056,長崎県,2022-09-23
上野,うえの,東京,35.71379,139.777043,東京都,1985-03-14
大宮,おおみや,上野,35.906439,139.62405,埼玉県,1982-06-23
小山,おやま,大宮,36.312747,139.806241,栃木県,1982-06-23
宇都宮,うつのみや,小山,36.559246,139.898389,栃木県,1982-06-23
那須塩原,なすしおばら,宇都宮,36.931956,140.020694,栃木県,1982-06-23
新白河,しんしらかわ,那須塩原,37.12331,140.188969,福島県,1982-06-23
郡山,こおりやま,新白河,37.398187,140.389363,福島県,1982-06-23
福島,ふくしま,郡山,37.754123,140.45968,福島県,1982-06-23
白石蔵王,しらいしざおう,福島,37.995485,140.633035,宮城県,1982-06-23
仙台,せんだい,白石蔵王,38.260027,140.882158,宮城県,1982-06-23
古川,ふるかわ,仙台,38.571192,140.967876,宮城県,1982-06-23
くりこま高原,くりこまこうげん,古川,38.74893,141.071785,宮城県,1990-03-10
一ノ関,いちのせき,くりこま高原,38.926514,141.138177,岩手県,1982-06-23
水沢江刺,みずさわえさし,一ノ関,39.145194,141.188803,岩手県,1985-03-14
北上,きたかみ,水沢江刺,39.281196,141.121221,岩手県,1982-06-23
新花巻,しんはなまき,北上,39.405839,141.17302,岩手県,1985-03-14
盛岡,もりおか,新花巻,39.701547,141.136599,岩手県,1982-06-23
いわて沼宮内,いわてぬまくない,盛岡,39.960155,141.216955,岩手県,2002-12-01
二戸,にのへ,いわて沼宮内,40.25997,141.286211,岩手県,2002-12-01
八戸,はちのへ,二戸,40.5092,141.431499,青森県,2002-12-01
七戸十和田,しちのへとわだ,八戸,40.719917,141.153948,青森県,2010-04-12
新青森,しんあおもり,七戸十和田,40.8275,140.693472,青森県,2010-04-12
奥津軽いまべつ,おくつがるいまべつ,新青森,41.145083,140.515444,青森県,2016-03-26
木古内,きこない,奥津軽いまべつ,41.677642,140.434004,北海道,2016-03-26
新函館北斗,しんはこだてほくと,木古内,41.9054,140.646525,北海道,2016-03-26
米沢,よねざわ,福島,37.909478,140.128209,山形県,1992-07-01
高畠,たかはた,米沢,37.992314,140.15281,山形県,1992-07-01
赤湯,あかゆ,高畠,38.047081,140.148978,山形県,1992-07-01
かみのやま温泉,かみのやまおんせん,赤湯,38.152259,140.27867,山形県,1992-07-01
山形,やまがた,かみのやま温泉,38.248098,140.327253,山形県,1992-07-01
天童,てんどう,山形,38.35989,140.369303,山形県,1999-12-04
さくらんぼ東根,さくらんぼひがしね,天童,38.42806,140.380677,山形県,1999-12-04
村山,むらやま,さくらんぼ東根,38.477078,140.386399,山形県,1999-12-04
大石田,おおいしだ,村山,38.595916,140.375349,山形県,1999-12-04
新庄,しんじょう,大石田,38.76256,140.306064,山形県,1999-12-04
雫石,しずくいし,盛岡,39.689244,140.974762,岩手県,1997-03-22
田沢湖,たざわこ,雫石,39.700363,140.722139,秋田県,1997-03-22
角館,かくのだて,田沢湖,39.591716,140.570988,秋田県,1997-03-22
大曲,おおまがり,角館,39.465712,140.479628,秋田県,1997-03-22
秋田,あきた,大曲,39.716748,140.129931,秋田県,1997-03-22
熊谷,くまがや,大宮,36.139627,139.389528,埼玉県,1982-11-15
本庄早稲田,ほんじょうわせだ,熊谷,36.218575,139.179739,埼玉県,2004-03-13
高崎,たかさき,本庄早稲田,36.322239,139.012354,群馬県,1982-11-15
上毛高原,じょうもうこうげん,高崎,36.693128,138.977579,群馬県,1982-11-15
越後湯沢,えちごゆざわ,上毛高原,36.935799,138.809227,新潟県,1982-11-15
浦佐,うらさ,越後湯沢,37.167488,138.922798,新潟県,1982-11-15
長岡,ながおか,浦佐,37.447787,138.853927,新潟県,1982-11-15
燕三条,つばめさんじょう,長岡,37.648824,138.939274,新潟県,1982-11-15
新潟,にいがた,燕三条,37.912299,139.060869,新潟県,1982-11-15
ガーラ湯沢,かーらゆざわえき,越後湯沢,36.950889,138.799528,新潟県,1990-12-20
安中榛名,あんなかはるな,高崎,36.362408,138.849589,群馬県,1997-10-01
軽井沢,かるいざわ,安中榛名,36.342889,138.635096,長野県,1997-10-01
佐久平,さくだいら,軽井沢,36.277929,138.464367,長野県,1997-10-01
上田,うえだ,佐久平,36.396579,138.249298,長野県,1997-10-01
長野,ながの,上田,36.643307,138.189101,長野県,1997-10-01
飯山,いいやま,長野,36.847642,138.359335,長野県,2015-03-14
上越妙高,じょうえつみょうこう,飯山,37.081813,138.249476,新潟県,2015-03-14
糸魚川,いといがわ,上越妙高,37.043631,137.861311,新潟県,2015-03-14
黒部宇奈月温泉,くろべうなづきおんせん,糸魚川,36.8742374,137.4814155,富山県,2015-03-14
富山,とやま,黒部宇奈月温泉,36.701384,137.213091,富山県,2015-03-14
新高岡,しんたかおか,富山,36.727004,137.010459,富山県,2015-03-14
金沢,かなざわ,新高岡,36.578117,136.648166,石川県,2015-03-14
小松,こまつ,金沢,36.402545,136.452926,石川県,2024-03-16
加賀温泉,かがおんせん,小松,36.320562,136.350337,石川県,2024-03-16
芦原温泉,あわらおんせん,加賀温泉,36.214542,136.235069,福井県,2024-03-16
福井,ふくい,芦原温泉,36.062057,136.223516,福井県,2024-03-16
越前たけふ,えちぜんたけふ,福井,35.895667,136.198889,福井県,2024-03-16
敦賀,つるが,越前たけふ,35.644767,136.076488,福井県,2024-03-16
```

この中にミニ新幹線や、特別な事情によって設置されたガーラ湯沢駅と博多南駅も含まれます。


# 変化のある日付を羅列

準備したcsvファイルをpandasで読み込んで調べてみます。まず開業の日付で駅を分けてhtmlのテーブルを作ります。

```python
import pandas as pd

df = pd.read_csv('eki.csv')
html = '<table></tr>\n'
for ind,dfi in df.sort_values('開業',kind='mergesort').groupby('開業'):
    eki = dfi['駅名']+'駅'
    eki = '<a href="https://ja.wikipedia.org/wiki/'+eki+'" target="_blank">'+eki+'</a>'
    a = '、'.join(eki)
    html += f"  <tr><td>{ind}</td><td>{a}</td>\n"
html += '</table>'
open('eki.html','w',encoding='utf-8').write(html)
```

（因み並べ替えは`.sort_values`を使って`kind='mergesort'`を指定したが、そうした方がいい理由に関しては前の記事「[pandasのsort_valuesで勝手に不規則に並べ替える問題の原因と対策](https://qiita.com/phyblas/items/e675296137fcaf486b7b)」に説明してあります）

実行したらテーブルのhtmlができて、このようなテーブルになります。wikiへのリンクも入れているので各駅の詳しくは調べられます。

<table></tr>
  <tr><td>1964-10-01</td><td><a href="https://ja.wikipedia.org/wiki/東京駅" target="_blank">東京駅</a>、<a href="https://ja.wikipedia.org/wiki/品川駅" target="_blank">品川駅</a>、<a href="https://ja.wikipedia.org/wiki/新横浜駅" target="_blank">新横浜駅</a>、<a href="https://ja.wikipedia.org/wiki/小田原駅" target="_blank">小田原駅</a>、<a href="https://ja.wikipedia.org/wiki/熱海駅" target="_blank">熱海駅</a>、<a href="https://ja.wikipedia.org/wiki/三島駅" target="_blank">三島駅</a>、<a href="https://ja.wikipedia.org/wiki/静岡駅" target="_blank">静岡駅</a>、<a href="https://ja.wikipedia.org/wiki/浜松駅" target="_blank">浜松駅</a>、<a href="https://ja.wikipedia.org/wiki/豊橋駅" target="_blank">豊橋駅</a>、<a href="https://ja.wikipedia.org/wiki/名古屋駅" target="_blank">名古屋駅</a>、<a href="https://ja.wikipedia.org/wiki/岐阜羽島駅" target="_blank">岐阜羽島駅</a>、<a href="https://ja.wikipedia.org/wiki/米原駅" target="_blank">米原駅</a>、<a href="https://ja.wikipedia.org/wiki/京都駅" target="_blank">京都駅</a>、<a href="https://ja.wikipedia.org/wiki/新大阪駅" target="_blank">新大阪駅</a></td>
  <tr><td>1972-03-15</td><td><a href="https://ja.wikipedia.org/wiki/新神戸駅" target="_blank">新神戸駅</a>、<a href="https://ja.wikipedia.org/wiki/西明石駅" target="_blank">西明石駅</a>、<a href="https://ja.wikipedia.org/wiki/姫路駅" target="_blank">姫路駅</a>、<a href="https://ja.wikipedia.org/wiki/相生駅" target="_blank">相生駅</a>、<a href="https://ja.wikipedia.org/wiki/岡山駅" target="_blank">岡山駅</a></td>
  <tr><td>1975-03-10</td><td><a href="https://ja.wikipedia.org/wiki/新倉敷駅" target="_blank">新倉敷駅</a>、<a href="https://ja.wikipedia.org/wiki/福山駅" target="_blank">福山駅</a>、<a href="https://ja.wikipedia.org/wiki/三原駅" target="_blank">三原駅</a>、<a href="https://ja.wikipedia.org/wiki/広島駅" target="_blank">広島駅</a>、<a href="https://ja.wikipedia.org/wiki/新岩国駅" target="_blank">新岩国駅</a>、<a href="https://ja.wikipedia.org/wiki/徳山駅" target="_blank">徳山駅</a>、<a href="https://ja.wikipedia.org/wiki/新山口駅" target="_blank">新山口駅</a>、<a href="https://ja.wikipedia.org/wiki/新下関駅" target="_blank">新下関駅</a>、<a href="https://ja.wikipedia.org/wiki/小倉駅" target="_blank">小倉駅</a>、<a href="https://ja.wikipedia.org/wiki/博多駅" target="_blank">博多駅</a></td>
  <tr><td>1982-06-23</td><td><a href="https://ja.wikipedia.org/wiki/大宮駅" target="_blank">大宮駅</a>、<a href="https://ja.wikipedia.org/wiki/小山駅" target="_blank">小山駅</a>、<a href="https://ja.wikipedia.org/wiki/宇都宮駅" target="_blank">宇都宮駅</a>、<a href="https://ja.wikipedia.org/wiki/那須塩原駅" target="_blank">那須塩原駅</a>、<a href="https://ja.wikipedia.org/wiki/新白河駅" target="_blank">新白河駅</a>、<a href="https://ja.wikipedia.org/wiki/郡山駅" target="_blank">郡山駅</a>、<a href="https://ja.wikipedia.org/wiki/福島駅" target="_blank">福島駅</a>、<a href="https://ja.wikipedia.org/wiki/白石蔵王駅" target="_blank">白石蔵王駅</a>、<a href="https://ja.wikipedia.org/wiki/仙台駅" target="_blank">仙台駅</a>、<a href="https://ja.wikipedia.org/wiki/古川駅" target="_blank">古川駅</a>、<a href="https://ja.wikipedia.org/wiki/一ノ関駅" target="_blank">一ノ関駅</a>、<a href="https://ja.wikipedia.org/wiki/北上駅" target="_blank">北上駅</a>、<a href="https://ja.wikipedia.org/wiki/盛岡駅" target="_blank">盛岡駅</a></td>
  <tr><td>1982-11-15</td><td><a href="https://ja.wikipedia.org/wiki/熊谷駅" target="_blank">熊谷駅</a>、<a href="https://ja.wikipedia.org/wiki/高崎駅" target="_blank">高崎駅</a>、<a href="https://ja.wikipedia.org/wiki/上毛高原駅" target="_blank">上毛高原駅</a>、<a href="https://ja.wikipedia.org/wiki/越後湯沢駅" target="_blank">越後湯沢駅</a>、<a href="https://ja.wikipedia.org/wiki/浦佐駅" target="_blank">浦佐駅</a>、<a href="https://ja.wikipedia.org/wiki/長岡駅" target="_blank">長岡駅</a>、<a href="https://ja.wikipedia.org/wiki/燕三条駅" target="_blank">燕三条駅</a>、<a href="https://ja.wikipedia.org/wiki/新潟駅" target="_blank">新潟駅</a></td>
  <tr><td>1985-03-14</td><td><a href="https://ja.wikipedia.org/wiki/上野駅" target="_blank">上野駅</a>、<a href="https://ja.wikipedia.org/wiki/水沢江刺駅" target="_blank">水沢江刺駅</a>、<a href="https://ja.wikipedia.org/wiki/新花巻駅" target="_blank">新花巻駅</a></td>
  <tr><td>1988-03-13</td><td><a href="https://ja.wikipedia.org/wiki/新富士駅" target="_blank">新富士駅</a>、<a href="https://ja.wikipedia.org/wiki/掛川駅" target="_blank">掛川駅</a>、<a href="https://ja.wikipedia.org/wiki/三河安城駅" target="_blank">三河安城駅</a>、<a href="https://ja.wikipedia.org/wiki/新尾道駅" target="_blank">新尾道駅</a>、<a href="https://ja.wikipedia.org/wiki/東広島駅" target="_blank">東広島駅</a></td>
  <tr><td>1990-03-10</td><td><a href="https://ja.wikipedia.org/wiki/くりこま高原駅" target="_blank">くりこま高原駅</a></td>
  <tr><td>1990-04-01</td><td><a href="https://ja.wikipedia.org/wiki/博多南駅" target="_blank">博多南駅</a></td>
  <tr><td>1990-12-20</td><td><a href="https://ja.wikipedia.org/wiki/ガーラ湯沢駅" target="_blank">ガーラ湯沢駅</a></td>
  <tr><td>1992-07-01</td><td><a href="https://ja.wikipedia.org/wiki/米沢駅" target="_blank">米沢駅</a>、<a href="https://ja.wikipedia.org/wiki/高畠駅" target="_blank">高畠駅</a>、<a href="https://ja.wikipedia.org/wiki/赤湯駅" target="_blank">赤湯駅</a>、<a href="https://ja.wikipedia.org/wiki/かみのやま温泉駅" target="_blank">かみのやま温泉駅</a>、<a href="https://ja.wikipedia.org/wiki/山形駅" target="_blank">山形駅</a></td>
  <tr><td>1997-03-22</td><td><a href="https://ja.wikipedia.org/wiki/雫石駅" target="_blank">雫石駅</a>、<a href="https://ja.wikipedia.org/wiki/田沢湖駅" target="_blank">田沢湖駅</a>、<a href="https://ja.wikipedia.org/wiki/角館駅" target="_blank">角館駅</a>、<a href="https://ja.wikipedia.org/wiki/大曲駅" target="_blank">大曲駅</a>、<a href="https://ja.wikipedia.org/wiki/秋田駅" target="_blank">秋田駅</a></td>
  <tr><td>1997-10-01</td><td><a href="https://ja.wikipedia.org/wiki/安中榛名駅" target="_blank">安中榛名駅</a>、<a href="https://ja.wikipedia.org/wiki/軽井沢駅" target="_blank">軽井沢駅</a>、<a href="https://ja.wikipedia.org/wiki/佐久平駅" target="_blank">佐久平駅</a>、<a href="https://ja.wikipedia.org/wiki/上田駅" target="_blank">上田駅</a>、<a href="https://ja.wikipedia.org/wiki/長野駅" target="_blank">長野駅</a></td>
  <tr><td>1999-03-13</td><td><a href="https://ja.wikipedia.org/wiki/厚狭駅" target="_blank">厚狭駅</a></td>
  <tr><td>1999-12-04</td><td><a href="https://ja.wikipedia.org/wiki/天童駅" target="_blank">天童駅</a>、<a href="https://ja.wikipedia.org/wiki/さくらんぼ東根駅" target="_blank">さくらんぼ東根駅</a>、<a href="https://ja.wikipedia.org/wiki/村山駅" target="_blank">村山駅</a>、<a href="https://ja.wikipedia.org/wiki/大石田駅" target="_blank">大石田駅</a>、<a href="https://ja.wikipedia.org/wiki/新庄駅" target="_blank">新庄駅</a></td>
  <tr><td>2002-12-01</td><td><a href="https://ja.wikipedia.org/wiki/いわて沼宮内駅" target="_blank">いわて沼宮内駅</a>、<a href="https://ja.wikipedia.org/wiki/二戸駅" target="_blank">二戸駅</a>、<a href="https://ja.wikipedia.org/wiki/八戸駅" target="_blank">八戸駅</a></td>
  <tr><td>2004-03-13</td><td><a href="https://ja.wikipedia.org/wiki/新八代駅" target="_blank">新八代駅</a>、<a href="https://ja.wikipedia.org/wiki/新水俣駅" target="_blank">新水俣駅</a>、<a href="https://ja.wikipedia.org/wiki/出水駅" target="_blank">出水駅</a>、<a href="https://ja.wikipedia.org/wiki/川内駅" target="_blank">川内駅</a>、<a href="https://ja.wikipedia.org/wiki/鹿児島中央駅" target="_blank">鹿児島中央駅</a>、<a href="https://ja.wikipedia.org/wiki/本庄早稲田駅" target="_blank">本庄早稲田駅</a></td>
  <tr><td>2010-04-12</td><td><a href="https://ja.wikipedia.org/wiki/七戸十和田駅" target="_blank">七戸十和田駅</a>、<a href="https://ja.wikipedia.org/wiki/新青森駅" target="_blank">新青森駅</a></td>
  <tr><td>2011-03-12</td><td><a href="https://ja.wikipedia.org/wiki/新鳥栖駅" target="_blank">新鳥栖駅</a>、<a href="https://ja.wikipedia.org/wiki/久留米駅" target="_blank">久留米駅</a>、<a href="https://ja.wikipedia.org/wiki/筑後船小屋駅" target="_blank">筑後船小屋駅</a>、<a href="https://ja.wikipedia.org/wiki/新大牟田駅" target="_blank">新大牟田駅</a>、<a href="https://ja.wikipedia.org/wiki/新玉名駅" target="_blank">新玉名駅</a>、<a href="https://ja.wikipedia.org/wiki/熊本駅" target="_blank">熊本駅</a></td>
  <tr><td>2015-03-14</td><td><a href="https://ja.wikipedia.org/wiki/飯山駅" target="_blank">飯山駅</a>、<a href="https://ja.wikipedia.org/wiki/上越妙高駅" target="_blank">上越妙高駅</a>、<a href="https://ja.wikipedia.org/wiki/糸魚川駅" target="_blank">糸魚川駅</a>、<a href="https://ja.wikipedia.org/wiki/黒部宇奈月温泉駅" target="_blank">黒部宇奈月温泉駅</a>、<a href="https://ja.wikipedia.org/wiki/富山駅" target="_blank">富山駅</a>、<a href="https://ja.wikipedia.org/wiki/新高岡駅" target="_blank">新高岡駅</a>、<a href="https://ja.wikipedia.org/wiki/金沢駅" target="_blank">金沢駅</a></td>
  <tr><td>2016-03-26</td><td><a href="https://ja.wikipedia.org/wiki/奥津軽いまべつ駅" target="_blank">奥津軽いまべつ駅</a>、<a href="https://ja.wikipedia.org/wiki/木古内駅" target="_blank">木古内駅</a>、<a href="https://ja.wikipedia.org/wiki/新函館北斗駅" target="_blank">新函館北斗駅</a></td>
  <tr><td>2022-09-23</td><td><a href="https://ja.wikipedia.org/wiki/武雄温泉駅" target="_blank">武雄温泉駅</a>、<a href="https://ja.wikipedia.org/wiki/嬉野温泉駅" target="_blank">嬉野温泉駅</a>、<a href="https://ja.wikipedia.org/wiki/新大村駅" target="_blank">新大村駅</a>、<a href="https://ja.wikipedia.org/wiki/諫早駅" target="_blank">諫早駅</a>、<a href="https://ja.wikipedia.org/wiki/長崎駅" target="_blank">長崎駅</a></td>
  <tr><td>2024-03-16</td><td><a href="https://ja.wikipedia.org/wiki/小松駅" target="_blank">小松駅</a>、<a href="https://ja.wikipedia.org/wiki/加賀温泉駅" target="_blank">加賀温泉駅</a>、<a href="https://ja.wikipedia.org/wiki/芦原温泉駅" target="_blank">芦原温泉駅</a>、<a href="https://ja.wikipedia.org/wiki/福井駅" target="_blank">福井駅</a>、<a href="https://ja.wikipedia.org/wiki/越前たけふ駅" target="_blank">越前たけふ駅</a>、<a href="https://ja.wikipedia.org/wiki/敦賀駅" target="_blank">敦賀駅</a></td>
</table>


# 各都道府県別

どの都道府県がどれくらい駅を持っているか、これも気になりますので、調べてみます。pandasを使ったらこのように1行で纏められます。
```python
print(df.groupby('県').apply(len).sort_values()[::-1].reset_index().groupby(0).apply(lambda x:'、'.join(x['県'])).sort_index()[::-1])
```

結果。それぞれの数の駅を持つ都道府県。
```
10                                             山形県
8                                          新潟県、岩手県
6                                          福岡県、静岡県
5                                      広島県、山口県、長野県
4                          兵庫県、秋田県、福井県、宮城県、熊本県、青森県
3     佐賀県、埼玉県、富山県、鹿児島県、愛知県、東京都、栃木県、石川県、福島県、群馬県、長崎県
2                                     岡山県、神奈川県、北海道
1                                  岐阜県、滋賀県、大阪府、京都府
```

山形県は一番多いですね。[ミニ新幹線](https://ja.wikipedia.org/wiki/ミニ新幹線)であるため殆ど在来線の特急と同じ扱いだからです。ミニ新幹線と特別な駅を除けば岩手県と新潟県が一番で7駅となります。それにしても3駅の都道府県が多いですね。

どの県がいつから新幹線駅を持つようになったかも調べてみます。

```python
print(df.groupby('県').apply(lambda x:x['開業'].min()).sort_values(kind='mergesort').reset_index().groupby(0).apply(lambda x:'、'.join(x['県'])))
```

```
1964-10-01    京都府、大阪府、岐阜県、愛知県、東京都、滋賀県、神奈川県、静岡県
1972-03-15                             兵庫県、岡山県
1975-03-10                         山口県、広島県、福岡県
1982-06-23                 埼玉県、宮城県、岩手県、栃木県、福島県
1982-11-15                             新潟県、群馬県
1992-07-01                                 山形県
1997-03-22                                 秋田県
1997-10-01                                 長野県
2002-12-01                                 青森県
2004-03-13                            熊本県、鹿児島県
2011-03-12                                 佐賀県
2015-03-14                             富山県、石川県
2016-03-26                                 北海道
2022-09-23                                 長崎県
2024-03-16                                 福井県
```

最後に新幹線ができたのは福井県ですね。今後中央新幹線が開業できたら山梨県も加わるでしょう。

このように新幹線を持つ都道府県はどんどん増えてきましたね。

# 新幹線の変化を地図で見る

次は早速地図で見てみたいです。使うのはfoliumという地図を表示する為のPythonライブラリです。ただし画像として出力するためにはseleniumライブラリもインストールする必要があります。
```
pip install folium selenium
```

時代によって変わっていく新幹線の駅と路線の地図描いて見てみましょう。
```python
import math
import pandas as pd
from PIL import Image,ImageDraw,ImageFont
import folium
import io

df = pd.read_csv('eki.csv').set_index('駅名')
df['年'] = df['開業'].str[:4].astype(int)

for nen in sorted(df['年'].unique()):
    lis_eki = df.index[df['年']<=nen]
    latlng = df.loc[lis_eki,['緯度','経度']].values
    loc = (latlng.max(0)+latlng.min(0))/2
    zoom = 9.5-math.log2(latlng[:,1].max()-latlng[:,1].min())
    fomap = folium.Map(loc,zoom_start=zoom,width=620,height=700,zoom_control=False)
    for eki in lis_eki:
        loc = df.loc[eki,['緯度','経度']].values
        r = (2024-df.loc[eki,'年'])*4
        iro = '#%02x33%02x'%(r,255-r)
        folium.Circle(loc,1,color=iro).add_to(fomap)
        
        maeeki = df.loc[eki,'前の駅']
        loc2 = None
        if(eki=='上野' and nen<1991):
            continue
        if(eki=='大宮' and nen<1985):
            continue
        if(maeeki in lis_eki):
            loc2 = df.loc[maeeki,['緯度','経度']].values
        elif(pd.notna(maeeki)):
            maemaeeki = df.loc[maeeki,'前の駅']
            if(maemaeeki in lis_eki):
                loc2 = df.loc[maemaeeki,['緯度','経度']].values
        
        if(loc2 is not None):
            folium.PolyLine([loc,loc2],color='#323e0c',weight=2).add_to(fomap,index=0)
    
    img = Image.open(io.BytesIO(fomap._to_png(1))).convert('RGB')
    llmm = latlng.max(0)-latlng.min(0)
    img = img.crop([0,350*(1-llmm[0]/llmm[1]),620,350*(1+llmm[0]/llmm[1])])
    font = ImageFont.truetype('Helvetica',24)
    ImageDraw.Draw(img).text((10,10),str(nen),(r,51,255-r),font=font)
    img.save('fomap%d.jpg'%nen,quality=95)
```

できた地図を見ながら簡単に解説しましょう。

### 1964年

![fomap1964.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/6ebe9477-1123-c566-6204-2f37a8fbafbf.jpeg)

新幹線が最初に開業したのは1964年で、東京駅から新大阪駅までの東海道新幹線です。当初はまだ14駅しかなかったです。

### 1972年

![fomap1972.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/7e508ddb-04f0-6df5-e1a8-fed7f8fdd583.jpeg)

1972年になったら新大阪駅から岡山駅までの山陽新幹線ができました。5駅追加されて19駅になりました。

### 1975年

![fomap1975.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/69af350f-cf43-702d-2ea3-d42a43533eab.jpeg)

1975年、山陽新幹線は博多駅まで延長しました。10駅も増えて29駅になりました。

### 1982年

![fomap1982.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/2d472a92-e8cb-fb37-6a86-7396ffb5262f.jpeg)

1982年になると、まず大宮駅から盛岡駅までの東北新幹線ができて、そして同年新潟駅までの上越新幹線もできました。駅の数は50になりました。

ただしあの時大宮駅が始点であり、東京から東北新幹線に乗ることはできなかったらしいです。

### 1985年

![fomap1985.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/3c88ed1e-fa74-e89e-3758-f0e619b8d895.jpeg)

1985年に、東北新幹線は上野駅まで延長したが、東京駅まではまだもう少し。この地図のスケールではわかりにくいのですが、上野駅と東京駅の新幹線はまだなかったです。

その他に東北新幹線では水沢江刺駅と新花巻駅が挿入されました。駅の数は53となりました。

### 1988年

![fomap1988.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/6167911e-3d14-9316-b749-484ea56e7f3b.jpeg)

1988年に、東海道・山陽新幹線の中では新富士駅、掛川駅、三河安城駅、新尾道駅、東広島駅、この5駅が挿入されました。これで駅の総数は58となりました。

### 1990年

![fomap1990.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/dc7861a3-c715-9642-7e8a-5defd1b783ce.jpeg)

1990年に、東北新幹線で宮城県のくりこま高原駅が挿入されました。同年に[博多南線](https://ja.wikipedia.org/wiki/博多南線)という特別な路線として福岡県の博多南駅も開業しました。似たような事情で、新潟県のスキー場にあるガーラ湯沢駅も冬限定で開業しました。駅の数は61になりました。

又、1991年に上野駅と東京駅の間の路線もできて、東京駅から東北新幹線に乗ることができるようになりました。

### 1992年

![fomap1992.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/505455a2-3bbb-1a8a-4392-e949d7dc9efd.jpeg)

1992年、ミニ新幹線である山形新幹線は開業しました。当初は山形駅までだけで5駅あります。駅の総数は66に。

### 1997年

![fomap1997.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/1ce0d51e-5f1e-e2d3-41f9-0ce0b99d1e87.jpeg)

1997年に、ミニ新幹線である秋田新幹線は秋田駅まで5駅開業しました。そして同年高崎駅から長野駅までの北陸新幹線5駅も開業しました。これによって76駅になりました。

因みに北陸新幹線と名乗ったが、当初は長野駅までしかなく、実際に北陸地方まで延長するのはその18年後。結構時間かかりましたね。

### 1999年

![fomap1999.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/0c60eba7-9a99-b3a3-aeff-269cc227ba64.jpeg)

1999年に、山陽新幹線に山口県山陽小野田市の厚狭駅が挿入それました。同年山形新幹線も新庄駅まで延長して、5駅増えてきました。駅の数は82になりました。

### 2002年

![fomap2002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/94f74e3b-b5b8-defe-ad0f-245b95dfd010.jpeg)

2002年、東北新幹線は青森県の八戸駅まで延長しました。これで3駅増えて85駅になりました。

### 2004年

![fomap2004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/0545cf24-0760-ded5-277d-de1307ecbf6d.jpeg)

2004年に、新八代駅から鹿児島中央駅までの九州新幹線5駅が開業しました。同じ日に上越新幹線の本庄早稲田駅が挿入されました。駅の数は91になりました。

ただしあの時の九州新幹線は山陽新幹線と繋がっていなくて孤島になったので、博多駅まで延長するまで7年の間は在来線に乗り換えるしかなくて不便そうです。

### 2010年

![fomap2010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/0ea8d296-c12c-7818-1d78-c2d473e52fd6.jpeg)

2010年、東北新幹線が新青森駅まで延長し、2駅増えて全部93駅に。これで東北新幹線は完成です。

### 2011年

![fomap2011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/4cc061b5-d4c3-cf38-787f-20e5f17fe5ba.jpeg)

2011年になると、漸く博多駅から新八代駅駅までの九州新幹線が開業しました。これで孤島が消えて新幹線は全部繋がることになりました。増えた駅の数は6駅で、全部99駅になりました。

尚、九州新幹線は博多南駅を通るが、博多南駅は九州新幹線に含まれていない、別の路線扱いです。

### 2015年

![fomap2015.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/3d4867e6-f839-a4fd-b844-a22bfc511332.jpeg)

2015年、北陸新幹線が金沢駅まで延長して、やっと本当の意味の北陸新幹線になりました。7駅が開業して、106駅になりました。

### 2016年

![fomap2016.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/125a4881-cdd7-5efb-f7ec-f0a0b6c4fa7d.jpeg)

2016年に、新函館北斗駅までの北海道新幹線3駅が開業して、これで109駅に。やっと北海道まで新幹線で行けることになりました。

### 2022年

![fomap2022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/f8ad0ef9-2758-b2ea-0c52-a32fa80135d8.jpeg)

2022年、武雄温泉駅から長崎駅までの西九州新幹線5駅は開業しました。これで114駅に。

ただしこの路線は他の新幹線の路線と繋がっていないので、また孤島になりました。しかも佐賀県内の問題により路線を繋ぐ計画すらまだ目処が立っていない状態になっているらしいので、この状態は長く続く恐れがありますね。

### 2024年

![fomap2024.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/bcbc416e-56d9-f578-f138-36fc52f7aec1.jpeg)

最後に2024年、北陸新幹線が敦賀駅まで延長しました。6駅増えて120駅になりました。

この路線は今後新大阪駅まで延長してループにする予定ですが、これもいつなのかまだ目処が立っていない状態です。

それに元々2027年に完成する予定の[中央新幹線](https://ja.wikipedia.org/wiki/中央新幹線)は延期されてしまったので、これから暫く新幹線に変化ない状態が続くでしょう。

# GUIで表示する

最後に、新幹線の歴史を簡単に調べられるようにPyQtを使ってGUIを作ってみます。

PyQtとfoliumによる地図のGUIの基本はこの記事に纏めてあるので参考に。

https://qiita.com/phyblas/items/eb260d0606f7a1800d7e

実装のコードです。
```python
import math,sys,re
import pandas as pd
import folium
from PyQt6.QtWidgets import QApplication,QWidget,QHBoxLayout,QVBoxLayout,QLabel,QSlider,QTableWidget,QTableWidgetItem
from PyQt6.QtGui import QColor
from PyQt6.QtCore import Qt
from PyQt6.QtWebEngineWidgets import QWebEngineView

class Qmado(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('新幹線の歴史を覗くGUI')
        self.setStyleSheet('font-family: Kaiti SC; font-size: 16px;')
        
        self.df = pd.read_csv('eki.csv').set_index('駅名')
        self.df['年'] = self.df['開業'].str[:4].astype(int)
        self.lis_eki = list(self.df.index)
        
        vbl = QVBoxLayout()
        self.setLayout(vbl)
        
        hbl1 = QHBoxLayout()
        vbl.addLayout(hbl1)
        
        self.nenlabel = QLabel()
        hbl1.addWidget(self.nenlabel)
        self.nenlabel.setStyleSheet('font-size: 20px;')
        
        self.nenslider = QSlider()
        hbl1.addWidget(self.nenslider)
        self.nenslider.setOrientation(Qt.Orientation.Horizontal)
        self.nenslider.setRange(1964,2024)
        self.nenslider.valueChanged.connect(self.nen_kawattara)
        
        hbl2 = QHBoxLayout()
        vbl.addLayout(hbl2)
        
        self.fowg = QWebEngineView(self)
        hbl2.addWidget(self.fowg)
        self.fowg.setFixedSize(620,620)
        
        self.qtable = QTableWidget()
        hbl2.addWidget(self.qtable)
        self.qtable.setFixedSize(360,620)
        self.qtable.setColumnCount(3)
        self.qtable.verticalHeader().setFixedWidth(30)
        for i,w in enumerate([140,80,90]):
            self.qtable.setColumnWidth(i,w)
        self.qtable.cellClicked.connect(self.cell_click)
        
        self.nenslider.setValue(1964)
        self.nen_kawattara(1964)

    def nen_kawattara(self,x):
        self.nen = x
        self.nenlabel.setText(str(x)+'年')
        lis_eki = list(self.df.index[self.df['年']<=self.nen])
        if(self.lis_eki!=lis_eki):
            self.lis_eki = lis_eki
            self.table_koushin()
        
    def table_koushin(self):
        df = self.df.loc[self.lis_eki]
        self.qtable.clear()
        self.qtable.setHorizontalHeaderLabels(['駅名','都道府県','開業日付'])
        self.qtable.setRowCount(len(df))
        for i,(eki,sr) in enumerate(df.iterrows()):
            qitem = QTableWidgetItem(eki)
            self.qtable.setItem(i,0,qitem)
            qitem.setToolTip(sr['読み方'])
            qitem.setBackground(QColor(30,50,50))
            qitem.setForeground(QColor(255,255,255))
            
            qitem = QTableWidgetItem(sr['県'])
            self.qtable.setItem(i,1,qitem)
            qitem.setBackground(QColor(50,50,20))
            qitem.setForeground(QColor(255,255,255))
            
            qitem = QTableWidgetItem(sr['開業'])
            self.qtable.setItem(i,2,qitem)
            r = (2024-df.loc[eki,'年'])*4
            qitem.setBackground(QColor(r,51,255-r))
            qitem.setForeground(QColor(255,255,255))
        
        self.chizu_koushin()
        
    def chizu_koushin(self):
        ar_latlng = self.df.loc[self.lis_eki,['緯度','経度']].values
        chuushin = (ar_latlng.max(0)+ar_latlng.min(0))/2
        zoom = 9.5-math.log2(ar_latlng[:,1].max()-ar_latlng[:,1].min())
        fomap = folium.Map(chuushin,zoom_start=zoom)
        
        for eki in self.lis_eki:
            latlng = self.df.loc[eki,['緯度','経度']].values
            r = (2024-self.df.loc[eki,'年'])*4
            iro = '#%02x33%02x'%(r,255-r)
            yomi = self.df.loc[eki,'読み方']
            ido = self.df.loc[eki,'緯度']
            keido = self.df.loc[eki,'経度']
            popup = folium.Popup(
                '<h4>%s駅</h4><h5>%s</h5>%.4f,%.4f'%(eki,yomi,ido,keido),
                auto_close=False
            )
            folium.CircleMarker(
                latlng,
                radius=4,
                weight=0,
                fill_color=iro,
                fill_opacity=1,
                popup=popup
            ).add_to(fomap)
            
            maeeki = self.df.loc[eki,'前の駅']
            latlng2 = None
            if((eki=='上野' and self.nen<1991) or (eki=='大宮' and self.nen<1985)):
                continue
            if(maeeki in self.lis_eki):
                latlng2 = self.df.loc[maeeki,['緯度','経度']].values
            elif(pd.notna(maeeki)):
                maemaeeki = self.df.loc[maeeki,'前の駅']
                if(maemaeeki in self.lis_eki):
                    latlng2 = self.df.loc[maemaeeki,['緯度','経度']].values
            
            if(latlng2 is not None):
                folium.PolyLine([latlng,latlng2],color='#323e0c',weight=2).add_to(fomap,index=0)
        
        html = fomap.get_root().render()
        self.lis_mkobj = re.findall(r'var (circle_marker_\S+)',html)
        self.fowg.setHtml(html)
    
    def cell_click(self,i):
        mkobj = self.lis_mkobj[i]
        self.fowg.page().runJavaScript(f'{mkobj}.openPopup(); null')


qAp = QApplication(sys.argv)
qmado = Qmado()
qmado.show()
qAp.exec()
```

実行したらこのようなGUIが出てきます。最初は1964年に開業した駅しか表示されません。

![截屏2025-01-19-16.43.12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/137aa500-82dd-6d7a-b997-67b01efee0c1.jpeg)

そして上のスライダーを調整することによってその年まで開業した新幹線駅が表示されます。色は開業の年によって違って、古い駅は赤で、新しい駅は青にしています。

![截屏2025-01-19-16.46.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/f0f883a3-c49e-4a27-8775-e8917fd25c6a.jpeg)

ズームして細部を見ることもできますし、点をクリックしたら駅名と詳細のポップアップが表示されます。又、右のテーブルの中の行をクリックしたらその駅のポップアップも立ち上がります。

![截屏2025-01-19-16.45.26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/6299a8d5-5cef-554d-441e-9ff54191e15b.jpeg)


# 終わりに

このように、新幹線の歴史の勉強のついでにPythonの運用の練習にもなります。一石二鳥ですね。