[Python][Pandas] DataFrameからXlsxWriterでEXCELにグラフを作る関数を作った

A function to create a chart in EXCEL from DataFrame

##この記事について

データフレームにまとめてあるデータをとりあえずエクセルでグラフ化したい時がありますが、なかなか使いやすいサンプルコードがなかったので、公式サイトの例を基に関数にしてみました。DataFrameとシート名を渡せばどんどんエクセルに追加できます。


##元のデータと結果

今回は、日本の４都市の気温、降水量データをまずはエクセルで用意しました。
![スクリーンショット 2021-02-03 212302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/82c4c66d-e705-2bab-751a-2101b9749d39.png)

これをDataFrameとして読み込んで、関数を呼び出して４種類のグラフをエクセルにシート別で出力します。
![スクリーンショット 2021-02-03 212644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/ae4b6fe3-966f-9d26-42ca-fb7b6383f3a8.png)

##コード
以下はエクセルを読み込むのではなく、そのままコピペすればデータごと読み込むように変えてあります。

```python

import pandas as pd

def makeChartFromDF(df, s_name):
    
    df.to_excel(writer, sheet_name=s_name)

    # Access the XlsxWriter workbook and worksheet objects from the dataframe.
    workbook = writer.book
    worksheet = writer.sheets[s_name]

    # Create a chart object.
    chart = workbook.add_chart({'type': 'line'})

     # Configure the series of the chart from the dataframe data.
    for i in range(len(df)):
        col = i + 1
        chart.add_series({
            'name':       [s_name, col, 0],
            'categories': [s_name, 0, 1, 0, len(df.columns)],
            'values':     [s_name,  col, 1, col, len(df.columns)],
        })

    # Configure the chart axes.
    chart.set_x_axis({'name': df.columns.name, 'position_axis': 'on_tick'})
    chart.set_y_axis({'name': df.index.name, 'major_gridlines': {'visible': False}})

    # Insert the chart into the worksheet.
    worksheet.insert_chart('B7', chart, {'x_scale': 1.5, 'y_scale': 1.5})
    
#df=pd.read_excel('SampleJapanCityTemperature.xlsx')  #このゆおにエクセルからDataFrameを読み込んでもいい

df = pd.DataFrame( {'都市': {0: '東京', 1: '東京', 2: '東京', 3: '東京', 4: '札幌', 5: '札幌', 6: '札幌', 7: '札幌', 8: '大分', 9: '大分', 10: '大分', 11: '大分', 12: '大阪', 13: '大阪', 14: '大阪', 15: '大阪'}, '項目': {0: '最高気温( °C)', 1: '平均気温( °C)', 2: '最低気温( °C)', 3: '降水量(mm)', 4: '最高気温( °C)', 5: '平均気温( °C)', 6: '最低気温( °C)', 7: '降水量(mm)', 8: '最高気温( °C)', 9: '平均気温( °C)', 10: '最低気温( °C)', 11: '降水量(mm)', 12: '最高気温( °C)', 13: '平均気温( °C)', 14: '最低気温( °C)', 15: '降水量(mm)'}, '1月': {0: 9.6, 1: 5.2, 2: 0.9, 3: 52.3, 4: -0.6, 5: -3.6, 6: -7.0, 7: 113.6, 8: 10.5, 9: 6.2, 10: 2.2, 11: 45.4, 12: 9.5, 13: 6.0, 14: 2.8, 15: 45.4}, '2月': {0: 10.4, 1: 5.7, 2: 1.7, 3: 56.1, 4: 0.1, 5: -3.1, 6: -6.6, 7: 94.0, 8: 11.1, 9: 6.9, 10: 2.7, 11: 65.2, 12: 10.2, 13: 6.3, 14: 2.9, 15: 61.7}, '3月': {0: 13.6, 1: 8.7, 2: 4.4, 3: 117.5, 4: 4.0, 5: 0.6, 6: -2.9, 7: 77.8, 8: 14.1, 9: 9.7, 10: 5.4, 11: 112.1, 12: 13.7, 13: 9.4, 14: 5.6, 15: 104.2}, '4月': {0: 19.0, 1: 13.9, 2: 9.4, 3: 124.5, 4: 11.5, 5: 7.1, 6: 3.2, 7: 56.8, 8: 19.3, 9: 14.5, 10: 9.9, 11: 129.3, 12: 19.9, 13: 15.1, 14: 10.7, 15: 103.8}, '5月': {0: 22.9, 1: 18.2, 2: 14.0, 3: 137.8, 4: 17.3, 5: 12.4, 6: 8.3, 7: 53.1, 8: 23.5, 9: 18.8, 10: 14.5, 11: 150.3, 12: 24.5, 13: 19.7, 14: 15.6, 15: 145.5}, '6月': {0: 25.5, 1: 21.4, 2: 18.0, 3: 167.7, 4: 21.5, 5: 16.7, 6: 12.9, 7: 46.8, 8: 26.5, 9: 22.4, 10: 18.9, 11: 273.8, 12: 27.8, 13: 23.5, 14: 20.0, 15: 184.5}, '7月': {0: 29.2, 1: 25.0, 2: 21.8, 3: 153.5, 4: 24.9, 5: 20.5, 6: 17.3, 7: 81.0, 8: 30.6, 9: 26.5, 10: 23.2, 11: 252.5, 12: 31.6, 13: 27.4, 14: 24.3, 15: 157.0}, '8月': {0: 30.8, 1: 26.4, 2: 23.0, 3: 168.2, 4: 26.4, 5: 22.3, 6: 19.1, 7: 123.8, 8: 31.8, 9: 27.3, 10: 23.8, 11: 172.2, 12: 33.4, 13: 28.8, 14: 25.4, 15: 90.9}, '9月': {0: 26.9, 1: 22.8, 2: 19.7, 3: 209.9, 4: 22.4, 5: 18.1, 6: 14.2, 7: 135.2, 8: 28.0, 9: 23.9, 10: 20.5, 11: 219.5, 12: 29.3, 13: 25.0, 14: 21.7, 15: 160.7}, '10月': {0: 21.5, 1: 17.5, 2: 14.2, 3: 197.8, 4: 16.2, 5: 11.8, 6: 7.5, 7: 108.7, 8: 22.9, 9: 18.6, 10: 14.5, 11: 120.9, 12: 23.3, 13: 19.0, 14: 15.5, 15: 112.3}, '11月': {0: 16.3, 1: 12.1, 2: 8.3, 3: 92.5, 4: 8.5, 5: 4.9, 6: 1.3, 7: 104.1, 8: 17.9, 9: 13.4, 10: 9.1, 11: 69.1, 12: 17.6, 13: 13.6, 14: 9.9, 15: 69.3}, '12月': {0: 11.9, 1: 7.6, 2: 3.5, 3: 51.0, 4: 2.1, 5: -0.9, 6: -4.1, 7: 111.7, 8: 13.0, 9: 8.5, 10: 4.1, 11: 34.4, 12: 12.3, 13: 8.6, 14: 5.1, 15: 43.8}} )

writer = pd.ExcelWriter('chartFromDataFrame.xlsx', engine='xlsxwriter')

for item in df['項目'].unique().tolist():
    df_tmp=df[df['項目']==item]
    df_tmp=df_tmp.drop('項目', axis=1)
    df_tmp=df_tmp.set_index('都市')
    df_tmp.columns.name='月'
    df_tmp.index.name=item
    makeChartFromDF(df_tmp, item)

writer.save()

```

##　参考
公式のpandas xlsxwriterのサイト・こちらのサンプルコードをベースにしました
https://pandas-xlsxwriter-charts.readthedocs.io/chart_legend.html

気温と降水量のデータはこちらから入手させていただきました。自分でグラフ作ってみるより、見やすいグラフなどが満載ですが・・・
https://weather.time-j.net/Stations/JP/tokyo

## 感想
時々、こういうグラフを作りたくなるので備忘録も兼ねて記事にします。

それにしても、東京と大分の気温の差はそれほどないのに、札幌はぜんぜん違うことに気づきました・・