乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

可視化

米失業保険申請者数のデータがあったので
可視化してみました。


解説動画はこちら



データはここにあります。

データソース:2020年03/28までの統計データ

米国労働省:

https://www.dol.gov/ui/data.pdf

アメリカ合衆国 労働省雇用管理局

https://oui.doleta.gov/unemploy/wkclaims/report.asp

これをcsvファイルにしておきます。
列は「N.S.A(日付)」「S.F.(申請数)」の2列分を用意します。




pandas を使ってデータを読み込みします。
import pandas as pd

df = pd.read_table("米失業申請者数データ20200328.csv")
df['day'] = pd.to_datetime(df['N.S.A'], format='%m/%d/%Y')
「N.S.A」列が日付の部分の文字列「m/d/y」形式になっているので
日付のデータに直します。

次に可視化ツールのplotlyの方ですが
普通はインストールされていないと思うので
インストールしていない方はpip install plotly
などでインストールしてください。

以下のコードがこのデータを可視化するコードです。
import plotly
plotly.offline.init_notebook_mode(connected=False)
data = [
    plotly.graph_objs.Scatter(x=df["day"], y=df["S.F."], name="Claims")
]
layout = plotly.graph_objs.Layout(
    width=1000, height=600,
    title="title",
    xaxis={"title":"Years"},
    yaxis={"title":"Claims"},
)
fig = plotly.graph_objs.Figure(data=data, layout=layout)
plotly.offline.iplot(fig, show_link=False) 

日付を横軸(x) , 申請者数を縦軸(y)にあてて
線グラフを作ります。

可視化の結果は・・・
スクリーンショット 2020-04-05 15.56.29

右上にplotlyのツール類が表示され、ズームインアウトや
選択など色々選んで操作できます。

一般的なpandas、matplotlibの可視化では
動かすことができないので
可視化された図表を動かして見ることのできる
plotlyはかなりの優れものです。

データの方を見てみると
1982年とリーマンショックのあった2009年に
かなり多くの申請があったことが見えました。

しかし2020年3月になると
ドーンと跳ね上がって・・・

スクリーンショット 2020-04-05 16.01.20

爆増しているのが見えます。
レポートの数値から見ると
失業申請者数は600万人を超えているみたいですね。

リーマンの時でさえ100万人に満たなかった訳で
今回の影響がどれだけヤバイのかがすぐにわかります。

このデータは3/28のデータ
今日は4/5なのでそこから1週間経ってるいるため
さらに倍増している可能性もあります。

一説によると
アメリカの労働人口の2割ほどが影響を受けているそうで
もし、日本でも同様の事態となると
数十万人 - 100万人単位で
影響を受ける方が増えると予想されます。

特にレストランやバー、映画館、ホテル、スポーツジム
などは営業停止しており
特定の製造業も工場の稼働停止をしています。

リーマンの時は稼働停止までは至っていなかったと思うので
10年前の大不況に比べると
はるかに大きな不況が目の前に来ています。

前回の余波は、自分も食らったので2年くらい
まともな仕事が無かったです。

今回、それを超えるようなことに
ならないことを願うばかりです。

エンジニアの対策としては
現状新規案件が白紙、撤回されたり
内定も取り消されるケースが増えているようです。

フリーランスになったり、転職活動は
かなり厳しくなると予想されるので
今雇用があるなら、そこでじっと騒動が収まるまで
耐えるしかないかなと思います。

頑張って乗り切れば
明るい未来が待っていると思いたい。

それでは。



 

新型コロナウイルスが流行ってきています。

ありがたいことに
データをまとめて頂いている方が
いらっしゃるので
そのデータを用いて可視化をしてみます。


解説動画はこちら




データの提供元は東洋経済新聞社の方のようです。
めちゃくちゃ感謝したいと思います。


新型コロナウイルス国内感染の状況
https://toyokeizai.net/sp/visual/tko/covid19/

制作:荻原 和樹(東洋経済オンライン編集部)
データソース:厚生労働省の報道発表資料。

更新履歴・ソースコード:GitHub
https://github.com/kaz-ogiwara/covid19/

さてそれではデータを可視化をしていきましょう。

まずは
ライブラリの読み込みです。

今回は下記のライブラリを用います。
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline


次に
データの読み込みです。
直接データを読み込み指定します。

file_path = 'https://toyokeizai.net/sp/visual/tko/covid19/csv/data.csv'
df = pd.read_csv(file_path)
df.head()


新No.
旧No.確定日年代性別居住地周囲の患者の発生※濃厚接触者\nの状況
0111/1530代神奈川県なし38名特定、健康観察終了
1221/2440代中国(武漢市)なし32名特定、健康観察終了
2331/2530代中国(武漢市)なし7名特定、健康観察終了
3441/2640代中国(武漢市)No.192名特定、健康観察終了
4551/2840代中国(武漢市)なし3名特定、健康観察終了

こんな感じのローデータですね。

年代や性別などで
日別の感染者の状況をまとめてくれています。


はじめに
性年代別で集計してみましょう。

年代の並びがアレなので先に指定しておきます。
# 年代の並びを指定
order = ['10歳未満', '10代', '20代','30代','40代','50代','60代','70代','80代','90代']
data = pd.crosstab(df['性別'],df['年代'])[order]
data
年代10歳未満10代20代30代40代50代60代70代80代90代
性別
01941112151231
4161017283318120

これをヒートマップにしてみましょう。
ヒートマップはseabornライブラリで可視化できます。
data = pd.crosstab( df['性別'],df['年代'])[order]
ax = sns.heatmap(data,annot=True, fmt="d")
ax.set_ylim(len(data), 0)
plt.title('性年代別感染者数')
plt.show()
download-4

棒グラフにもしてみます。
棒グラフはseabornでは
countplotで可視化できます。
sns.countplot(y="年代", hue="性別",data=df,order=order)
plt.title('性年代別感染者数')
plt.show()

download-3
50-60代の男性の感染者が多いですね。

全体的には女性に比べると
男性の方が感染する方が多いようです。

男性の方がかかりやすいのかどうかは
このデータからは分かりませんね。



次に日別です。

日の並びも先に指定します。
date_order = ['1/15', '1/24', '1/25', '1/26', '1/28', '1/29', '1/30', '1/31','2/4', '2/5', '2/11',
       '2/13', '2/14', '2/15', '2/16', '2/17', '2/18', '2/19', '2/20', '2/21',
       '2/22', '2/23', '2/24', '2/25', '2/26', '2/27', '2/28', '調査中']
plt.figure(figsize=(16,9))
sns.countplot(x="確定日", hue="性別",data=df,order=date_order)
plt.title('日別感染者数')
plt.show()
download-2

日別の性別での可視化です。

男女を積み上げ棒グラフにしてみます。
data = pd.crosstab(df['性別'],df['確定日'])[date_order].T

fig = plt.figure(figsize=(16,9))
ax = fig.add_subplot(1, 1, 1)
ax.bar(date_order, data['男'], label='男')
ax.bar(date_order, data['女'], bottom=data['男'], label='女')
ax.legend()
plt.title('日別感染者数')
plt.show()
download-1
2/22,2/27に感染者数が激増していますね。

グラフを累積にしてみます。
累積のデータを先に作って
それを可視化しています。

numpyのcumsumで累積データを作ることができます。
data = pd.crosstab(df['性別'],df['確定日'])[date_order]
data2 = np.cumsum(data.T)

fig = plt.figure(figsize=(16,9))
ax = fig.add_subplot(1, 1, 1)
ax.bar(date_order, data2['男'], label='男')
ax.bar(date_order, data2['女'], bottom=data2['男'], label='女')
ax.legend()
plt.title('日別累積感染者数')
plt.show()
download


最後に都道府県別でみてみましょう。
data = pd.crosstab(df['居住地'],df['性別'])
data2 = data.sort_values('男',ascending=True)
data2


fig = plt.figure(figsize=(16,9))
ax = fig.add_subplot(1, 1, 1)
ax.barh(data2.index, data2['男'], label='男')
ax.barh(data2.index, data2['女'], left=data2['男'], label='女')
ax.legend()
plt.title('都道府県別感染者数')
plt.show()
download-5

北海道がすごいことになっていますね。

2番目に東京と愛知です。

地域差はかなりあると思いますが
そもそも目には見えないので
どこに潜んでいるかは
正直感じることもできないと思います。

企業の中には
在宅勤務を始める会社も出てきていて

人混みの中に出ないことが
感染予防につながると思いますので
リモートワークはどんどん広がっていくと
いーなーと思っています。

まあ
我々エンジニアは
客先に行くことなんて稀なので
全然在宅でも仕事できちゃいますよね。

2,3月は
大人しくしていた方が
良さそうな気はしますね。

この機会に
Pythonプログラミングを
覚えてみてはいかがでしょうか?

Youtubeなどでも
講座を公開していますので
ぜひみてみてください。

それでは。

グランメゾン東京をみているので
ミシュランの三つ星店が気になってしまいました。

ミシュランの星のついたお店群を
いい感じのライブラリがあったので
可視化してみました。

解説動画はこちら



さて今回使用する可視化のライブラリは
Foliumです。

緯度経度を使用して
いい感じに地図にマッピングできます。

foliumを使うにはインストールしないといけません

まずはインストールしておきましょう。

pip install folium

可視化するにはデータが必要です。

次のようなデータを作りました。
スクリーンショット 2019-12-29 20.31.33

必要な項目としては
お店の名前、星の数、ジャンル、住所、緯度経度などが必要です。

データを集めたら
Foliumを使って可視化です。

地図にマッピングした
HTMLファイルを作成することができます。

実際に作成したコードを貼っておきます。
import folium
from folium.features import CustomIcon
import pandas as pd

stars = {
'一つ星'        :'star1.png',
'二つ星'        :'star2.png',
'三つ星'        :'star3.png',
'ビブグルマン'  :'starbib.png'
}

def makeicon(icon_image):
    icon = CustomIcon(
    icon_image=icon_image,
    icon_size=(30, 30),
    icon_anchor=(30, 30),
    shadow_image='',
    shadow_size=(5, 5),
    shadow_anchor=(4, 4),
    popup_anchor=(-3, -3))
    return icon

def make_maker(r):
    tmp = folium.Marker(
        location = [r['longitude'],r['latitude']], 
        popup    = r['name'] + ' : ' + r['genre'],
        tooltip  = r['name'] + ' : ' + r['genre'] + ' : ' + r['address'].replace('東京都',''),
        icon     = makeicon(stars[r['star']]))
    return tmp

michelin_data = pd.read_table('michelin_data_2020.csv')

plot_map = folium.Map(location=[35.6725175,139.7210145] ,  zoom_start=12)

star1_group = folium.FeatureGroup(name="一つ星").add_to(plot_map)
star2_group = folium.FeatureGroup(name="二つ星").add_to(plot_map)
star3_group = folium.FeatureGroup(name="三つ星").add_to(plot_map)
bib_group   = folium.FeatureGroup(name="ビブグルマン").add_to(plot_map)

for i, r in michelin_data[michelin_data['star']=='一つ星'].iterrows():
    star1_group.add_child(make_maker(r))
for i, r in michelin_data[michelin_data['star']=='二つ星'].iterrows():
    star2_group.add_child(make_maker(r))
for i, r in michelin_data[michelin_data['star']=='三つ星'].iterrows():
    star3_group.add_child(make_maker(r))
for i, r in michelin_data[michelin_data['star']=='ビブグルマン'].iterrows():
    bib_group.add_child(make_maker(r))

folium.LayerControl().add_to(plot_map)
plot_map.save("mishelin_all_maps.html")

コードの説明ですが
まず星を出し分けるためにカスタムアイコンを用います。

CostomIconをインポートしておきます。

folium.Mapで初期マップを作ります。
緯度経度とズーム値を指定して
どこの地点から始めるのかを指定できます。

この初期マップにお店を一軒ずつ加えていきます。

グループ化しておくと
アイコンを点けたり消したり出来るので
星の種別ごとにグループ化しておきます。

グループごとにお店を加えて
LayerControlで出し分けをするための
パーツを作れます。

最後saveでHTMLファイルに出力をして
おしまいです。

出来上がりはこんな感じです。
スクリーンショット 2019-12-29 20.39.52

3つ星のお店だけ表示させました。

Foliumでは星ごとに出し入れ出来るので
右上のパーツを押してみてください。


出来上がりをリンクしておきますね。
ミシュランの3つ星のお店

400店舗ほどあるので
行きたい方はぜひ使ってみてください。

さて
緯度経度を用いた可視化も
Pythonを使えば簡単にできます。

ぜひ試してみてくださいね

グランメゾン東京の最終回も楽しみですね!!!

それでは
 

乃木坂46の情報を集めて
可視化してみました。

動画はこちら



使用しているTableauはこちらです。

 


さて
色々みていきましょう。
全体像はこんな感じですね。

氏名生年月日年齢出身地血液型星座身長(cm)
1期生秋元 真夏1993/08/2026埼玉県B型しし座154
1期生生田 絵梨花1997/01/2222東京都A型みずがめ座160
2期生伊藤 純奈1998/11/3021神奈川県A型いて座166
3期生伊藤 理々杏2002/10/0817沖縄県B型てんびん座154
1期生井上 小百合1994/12/1424埼玉県B型いて座156
3期生岩本 蓮加2004/02/0215東京都B型みずがめ座157
3期生梅澤 美波1999/01/0620神奈川県A型やぎ座170
3期生大園 桃子1999/09/1320鹿児島県O型おとめ座156
2期生北野 日奈子1996/07/1723北海道O型かに座158
3期生久保 史緒里2001/07/1418宮城県O型かに座159
1期生齋藤 飛鳥1998/08/1021東京都O型しし座158
3期生阪口 珠美2001/11/1018東京都A型さそり座161
2期生佐々木 琴子1998/08/2821埼玉県A型おとめ座163
3期生佐藤 楓1998/03/2321愛知県A型おひつじ座161
1期生白石 麻衣1992/08/2027群馬県A型しし座162
2期生新内 眞衣1992/01/2227埼玉県B型みずがめ座165
2期生鈴木 絢音1999/03/0520秋田県O型うお座160
1期生高山 一実1994/02/0825千葉県A型みずがめ座162
2期生寺田 蘭世1998/09/2321東京都不明てんびん座155
1期生中田 花奈1994/08/0625埼玉県A型しし座158
3期生中村 麗乃2001/09/2718東京都不明てんびん座167
1期生樋口 日奈1998/01/3121東京都A型みずがめ座159
1期生星野 みなみ1998/02/0621千葉県B型みずがめ座155
2期生堀 未央奈1996/10/1523岐阜県O型てんびん座160
1期生松村 沙友理1992/08/2727大阪府B型おとめ座164
3期生向井 葉月1999/08/2320東京都A型おとめ座152
2期生山崎 怜奈1997/05/2122東京都B型ふたご座164
3期生山下 美月1999/07/2620東京都O型しし座159
3期生吉田 綾乃クリスティー1995/09/0624大分県A型おとめ座161
3期生与田 祐希2000/05/0519福岡県O型おうし座152
2期生渡辺 みり愛1999/11/0120東京都O型さそり座153
1期生和田 まあや1998/04/2321広島県O型おうし座160
4期生遠藤 さくら2001/10/0318愛知県不明てんびん座160
4期生賀喜 遥香2001/08/0818栃木県A型しし座166
4期生掛橋 沙耶香2002/11/2017岡山県B型さそり座156
4期生金川 紗耶2001/10/3118北海道O型さそり座164
4期生北川 悠理2001/08/0818カリフォルニア州不明しし座163
4期生柴田 柚菜2003/03/0316千葉県A型うお座160
4期生清宮 レイ2003/08/0116埼玉県O型しし座162
4期生田村 真佑1999/01/1220埼玉県A型やぎ座158
4期生筒井 あやめ2004/06/0815愛知県O型ふたご座160
4期生早川 聖来2000/08/2419大阪府A型おとめ座164
4期生矢久保 美緒2002/08/1417東京都B型しし座152

こんなデータを用いて統計情報を作ってみました。

乃木坂46と言っているのに
43人しかいませんねーー

増えたり減ったりを繰り返しているようです。

43人の
平均的な身長は160くらいになり
平均年齢は20.5歳でした

最高年齢は
27歳が3名

最年少は
15歳が2名ですね。

最高身長は170cmが一人
最低身長は152cmが3名でした。

ここからはカテゴリ別で見ていきましょう。


まずは期別です
スクリーンショット 2019-12-07 17.27.41
よく知りませんが1-4期まであり、
人数は大体どの期も10人前後のようです。
年齢は1期の方から若くなっていきますね。

続いて血液型別です。

スクリーンショット 2019-12-07 17.27.29

血液型はA型が最も多くついでO,B

不明が数人いますが
なんとAB型はいないようですね。

乃木坂46になるにはAB型はダメなのかも知れませんねwww


星座別だとしし座、水瓶座、おとめ座が多いですね。

スクリーンショット 2019-12-07 17.27.56

アイドルになりにくい星座なんてのも
ありえるかも知れませんが、これだけだと
分かりませんね。

お次は都道府県別です。

スクリーンショット 2019-12-07 17.28.06
さすがに東京都は多いですね。
ついで埼玉でした。

東京の近辺は乃木坂46になるのには有利なのかも
知れません。

一人カリフォルニア出身がいますね
「欧米か!!!」
っと突っ込んであげましょう。



最後に名前の読み数です。
スクリーンショット 2019-12-07 17.28.15

まあ、女性の名前って2,3文字が多いので
しょうがありませんが、やはりアイドルの名前は
3文字以内が良さそうですね。






日本で一番有名なマークである

安産祈願マークを
プログラムで作ってみましょう!!!


動画はこちら



さて
作り方は
numpyとmatplotlibを用いて
マークを描いていきます。

widgetも用いて
うねうね変形できるようにもします。

ソースはこちら
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider, IntSlider,Select
%matplotlib inline

r = IntSlider(min=1, max=8, step=1, value=5)
t = FloatSlider(min=1.0, max=1.5, step=0.1, value=1.0)
c = Select(options=['black', 'red', 'blue','green'],
    value='black',description='coler : ',disabled=False)

@interact(r=r,t=t,c=c)
def plot_man(r,t,c):
    plt.figure(figsize=(10,9))
    plt.axes().set_aspect('equal', 'datalim')
    
    # circle 1
    x = [np.sin(np.radians(_x))*r for _x in np.linspace(-180,180,721)]
    y = [np.cos(np.radians(_y))*r*t for _y in np.linspace(-180,180,721)]
    plt.plot(x, y, c)
    
    # circle 2
    x2 = [i*0.7 for i in x]
    y2 = [i*0.7 for i in y]
    plt.plot(x2, y2, c)
    
    # line
    x3 = [0,0]
    y3 = [min(y)*1.25,max(y)*1.25]
    plt.plot(x3, y3, c)
    
    # lines
    x4 = [i*1.2 for i in x]
    y4 = [i*1.2 for i in y]
    for i in range(16):
        x5 = [x[i*45],x4[i*45]]
        y5 = [y[i*45],y4[i*45]]
        plt.plot(x5, y5, c)
    
    plt.xlim([-20,20])
    plt.ylim([-20,20])
    plt.show()



結果はこうなります。

スクリーンショット 2019-07-28 15.47.34


rで円の半径を変更
tで楕円の倍率を変更
colorで色を変更です。

楕円は
円の縦横方向を n 倍にすることで実現しています。

なので
縦方向であれば
xの値はそのままに
yの値の倍率を変えてあげると
縦方向の楕円になります。

今回のやり方では
まず半径を決めて円を用意します。
内側の円は1つめの円の倍率を変えただけです。

縦棒はxの値が0でyの値を変化させることで
実現させ、外側の棒たちは

大きな円を用意し
1つめの円から外側の円に向かう値で
描いています。

一応16本になるみたいなので
22.5度の角度になるような計算で
座標を求めています。

全部足すと
安産マークになります!!!!!!!




せっかくなので
GIFも作ってみましょう


matplotlibではアニメーション機能で
mp4やgifも作れますが
環境によっては動かないこともあり

今回は
画像をたくさん生成して
無理くりGIFに落とし込みます。


ソースはこちら
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider, IntSlider,Select
import os

data_dir = 'anzan_data/'
if not os.path.exists(data_dir):
    os.makedirs(data_dir)

for a in range(30):
    plt.figure(figsize=(3,3))
    plt.axes().set_aspect('equal', 'datalim')
    plt.tick_params(labelbottom=False,
                    labelleft=False,
                    labelright=False,
                    labeltop=False)
    plt.tick_params(bottom=False,
                    left=False,
                    right=False,
                    top=False)
    plt.xlim([-20,20])
    plt.ylim([-20,20])
    c ='black'
    n = (np.abs(np.sin(a))+1)
    # circle 1
    x = [np.sin(np.radians(_x))*8 for _x in np.linspace(-180,180,721)]
    y = [np.cos(np.radians(_y))*8*n for _y in np.linspace(-180,180,721)]
    plt.plot(x, y, c)

    # circle 2
    x2 = [i*0.7 for i in x]
    y2 = [i*0.7 for i in y]
    plt.plot(x2, y2, c)

    # line
    x3 = [0,0]
    y3 = [min(y)*1.25,max(y)*1.25]
    plt.plot(x3, y3, c)

    # lines
    x4 = [i*1.2 for i in x]
    y4 = [i*1.2 for i in y]
    for i in range(16):
        x5 = [x[i*45],x4[i*45]]
        y5 = [y[i*45],y4[i*45]]
        plt.plot(x5, y5, c)
    file_name = data_dir + 'tmp_{0:02}.png'.format(a)
    plt.savefig(file_name)

images = []
for a in range(30):
    file_name = data_dir + 'tmp_{0:02}.png'.format(a)
    img = Image.open(file_name)
    images.append(img)

gif_name = 'anzan.gif'
images[0].save(gif_name,save_all=True, append_images=images[1:], optimize=False, duration=2, loop=0)





結果はこうなります。


anzan
びろんびろん動くのが
気持ちいいですよねーーーー


はい
周りのに安産祈願の方がいたら
是非送ってあげましょう!!

きっと喜ばれること
間違いなし




今回はここまでです。

それでは


 

このページのトップヘ