Pythonで東京都内 62区市町村の新型コロナウイルス陽性者数 推移グラフを一気に作る

# 目的
都内在住・在勤の者として、細かく区市町村ごとの陽性者数推移が知りたかったので開発しました。
同じ都内といっても、区市町村ごとに傾向が違っています。

【今回作ったもの】
https://nobukuni-hyakutake.github.io/covid19tokyo/
の下の方の区市町村名をクリックするとグラフが表示されます。例：
![shinjuku0806q.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1802863/80af91af-c26d-670a-1a7f-4acb765fb5d2.png)
原則毎日更新して公開しています。
なお、同サイトの上方にある分布マップの解説は[こちらの記事](https://qiita.com/Nobukuni-Hyakutake/items/bb6e6c529bf0078af02c)をご覧ください。

# 環境
* 言語：Python3.9
* 使用ライブラリ： データ前処理はPandasとNumpy、グラフ作成はPlotly
* 使用サービス： GitHub pages

# コード解説
[東京都の公開しているCSV](https://catalog.data.metro.tokyo.lg.jp/dataset/t000010d0000000085)は、各区市町村の各日付に対する累計陽性者数です。ここからPandasを使って各区市町村の1日ごとや、7日間ごとの陽性者数を出しました。また、各区市町村の人口を付けています。全体をCSV出力したものは[こちら](https://raw.githubusercontent.com/Nobukuni-Hyakutake/covid19tokyo/main/docs/covid19tokyo_preprocessed.csv)です。

```covid19tokyo_preprocessed.csv(抜粋)
,group_code,date,count_sum,count_1day,count_7days,count_14days,last7days_ratio,last_day,Unnamed: 0,area,label,ruby,population,pref,en,number,jp_order
0,131016,2020-04-22,22.0,3.0,6.0,13.0,0.8571428571428571,2021-08-05,0,特別区,千代田区,ちよだく,65942.0,東京都,Chiyoda,0,35
1,131016,2020-04-23,22.0,0.0,4.0,13.0,0.4444444444444444,2021-08-05,0,特別区,千代田区,ちよだく,65942.0,東京都,Chiyoda,0,35
2,131016,2020-04-24,23.0,1.0,4.0,13.0,0.4444444444444444,2021-08-05,0,特別区,千代田区,ちよだく,65942.0,東京都,Chiyoda,0,35
3,131016,2020-04-25,23.0,0.0,4.0,13.0,0.4444444444444444,2021-08-05,0,特別区,千代田区,ちよだく,65942.0,東京都,Chiyoda,0,35
```

その後の、推移グラフ作成についてを詳しく解説します。
62区市町村+東京都全体(以下、各自治体)で、合計63回グラフ作成をfor文で繰り返します。各自治体には、あらかじめ0~62のnumberを振ってあります。

```python:main.py
for i in range (63):
```

iに対応した各自治体のデータだけを、データフレームから取り出します。人口で割って10万人あたりの数を出します。
なおステージ3基準、4基準の数字はそれぞれ１週間あたり15人、25人を７で割った数字です。

```python:main.py
    dfgraph00201=out.loc[(out['number']==i),['group_code','label','ruby','date','count_1day','count_7days','population','en','number']].copy().reset_index()
    label00201=dfgraph00201['label'][0]
    en00201=dfgraph00201['en'][0]
    title00201=dfgraph00201['label'][0]+' 新型コロナウイルス陽性者数 スマートフォンは横向きにして下さい'
    dfgraph00201['sevendays_ave']=round((dfgraph00201['count_7days']/7)/dfgraph00201['population']*100000,1)
    dfgraph00201['count_1day_p']=round(dfgraph00201['count_1day']/dfgraph00201['population']*100000,1)
    dfgraph00201['stage4']=3.6
    dfgraph00201['stage3']=2.1
```

１日ごとの陽性者数の棒グラフ部分を作ります。hover(マウスオーバーさせると出てくるテキスト)を表示させたくないのでhoverinfo = "none"とします。

```python:main.py
    fig00202=go.Bar(
        x=dfgraph00201["date"], y=dfgraph00201["count_1day_p"], name='10万人あたり',
        marker={"color": "#99cc66"},
        hoverinfo = "none",
        )
```

7日間平均の陽性者数の折れ線グラフ部分を作ります。

```python:main.py
    fig00203=go.Scatter(
        x=dfgraph00201["date"], y=dfgraph00201["sevendays_ave"], name='10万人あたり7日間平均',
        line={"color": "#cc6600","width":2},
    )
```

ステージ３、４の破線を作ります。

```python:main.py
    figstage4=go.Scatter(
        x=dfgraph00201["date"], y=dfgraph00201["stage4"], name='ステージ4基準', 
        line={"width":2, "color": "red", "dash":"dash"},
        hoverinfo = "none"
)

    figstage3=go.Scatter(
        x=dfgraph00201["date"], y=dfgraph00201["stage3"], name='ステージ3基準',
        line={"width":2, "color": "#ffcc00", "dash":"dash"},
        hoverinfo = "none"
    )
```

フォントサイズ、グラフタイトルの設定をします。

```python:main.py
    layout=go.Layout(
        font=dict(size=20),
        title={"text":title00201,
        },
```
このrangeselectorの設定によって、表示期間を全期間または直近３ヶ月間か、グラフを見る人がクリックで選べます。plotlyは、こういうインタラクティブなグラフが作れて便利です。

```python:main.py
        xaxis={
            "linecolor": "black",
            "rangeselector":{
                "buttons":[
                    {"label":"全期間","step":"all"},
                    {"label":"直近3ヵ月間","step":"month","count":3,"stepmode":"backward"}
                ],
            },
            "type":"date",
        }, 
```

y軸のタイトルと色、プロット部分全体の背景色を設定

```python:main.py
        yaxis={
            "title":{
            "text": '10万人あたり',
            },
        "linecolor": "black",   
            },
        hovermode='x',
        plot_bgcolor="#ffffff",
        )
```
ここまでで作ったグラフオブジェクトを全て、Figureとして登録します。

```python:main.py
    fig04=go.Figure(data=[fig00202, fig00203, figstage4, figstage3], layout=layout)
```

軸、凡例の調整

```python:main.py
    fig04.update_yaxes(
        rangemode="nonnegative"
        )
    fig04.update_layout(legend_orientation="h")
    fig04.update_layout(legend={"x":0,"y":-0.18})
```

最後の日にannotation(注釈のこと。上で出した例だと、一番直近の日に「21/8/4: 47.8」と書いてあるテキストボックスと矢印の部分)をつけます。
デフォルトだと見づらいので、ax=-80, ay=-80としてプロットの左上側に表示されるように設定しました。

```python:main.py
    sevendays_ave_lastday=dfgraph00201.loc[(dfgraph00201['date']==last_day1),['sevendays_ave']].mean()[0]
    fig04.update_layout(
        annotations=[
            go.layout.Annotation(
                x=last_day1,
                y=sevendays_ave_lastday,
                xref="x",
                yref="y",
                text=str(last_day1.year)[2:4]+"/"+str(last_day1.month)+"/"+str(last_day1.day)+": "+str(sevendays_ave_lastday),
                showarrow=True,
                arrowhead=1,
                bgcolor="#cc6600",
                font={"size":15,"color":"black"},
                ax=-80,
                ay=-80,
                opacity=0.7,
            )
        ]
    )
```

余白の調整。また、x軸の表示形式が、デフォルトだと"Mar 2021"など英語なので日本式の21/3/1という形にしました。

```python:main.py
    fig04.update_layout(
        margin={"t":120}
        )
    fig04.update_yaxes(automargin=False)
    fig04.update_xaxes(type='date', tickformat="%y/%-m/%-d", tick0='2020-05-01', dtick="M2") 
```

最後に、"[各自治体名]_g.html"というファイル名で出力します。例えば新宿区だったら"Shinjuku_g.html"です。

```python:main.py
    fig04.write_html("docs/"+en00201+"_g.html")
```
以上を前述のfor文で繰り返すことで、各自治体63箇所のグラフの出力が一気にできます。
私のMacBook Air (CPU:1.1 GHz クアッドコアIntel Core i5) ではデータ取り込み・前処理・全てのグラフ出力までを15秒で処理できました。

# コード全文
データ取り込み、前処理も含めた全文はこちらをご参照ください。
https://github.com/Nobukuni-Hyakutake/covid19tokyo

# 参考サイト
見栄えの調整で参考にさせていただきました。

https://qiita.com/shu32/items/5da9727e3c050350757f

軸の日付表示形式で参考にさせていただきました。

https://kiseno-log.com/2020/09/19/plotly-express%E3%81%A7%E8%BB%B8%E3%81%AE%E6%97%A5%E4%BB%98%E8%A1%A8%E7%A4%BA%E5%BD%A2%E5%BC%8F%E3%81%AE%E5%A4%89%E6%9B%B4%E6%96%B9%E6%B3%95/

# 参考文献
[Pythonインタラクティブ・データビジュアライゼーション入門](https://www.asakura.co.jp/books/isbn/978-4-254-12258-9/)

# 終わりに
MITライセンスとして公開しておりますので、東京都以外の道府県で同様のグラフを作られる際はどうぞ参考にしてみて下さい。
【今回作ったもの】
https://nobukuni-hyakutake.github.io/covid19tokyo/
下の方の区市町村名のリンクをクリックすると、グラフが表示されます。
【例：新宿区はこちらです】
https://nobukuni-hyakutake.github.io/covid19tokyo/Shinjuku_g.html
原則毎日、グラフを更新しています。
最後になりましたが感染された方へお見舞い申し上げます。