Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

pythonでグラフ付きエクセルファイルを自動出力

最近取得したcsvファイルからexcelファイルにコピーしてグラフ化して報告することが多くなってきた。
面倒なので自動化出来ないのかな??と思い調べてみたところpythonを用いれば結構簡単にexcelにデータの書き込みとエクセル出力できることを発見!!
早速実施してみると、本当に簡単!!
今回はこちらの方法を備忘録としてまとめていきます!!



■環境構築

今回用いるpythonのバージョンですが、
Python 3.7.3
です。
といっても、3.8系や3.6系でも試してみたのですが同じ方法で実施できました。

pythonexcelファイルに出力するにあたり、
openpyxl
を用います。

【openpyxltとは】
openpyxlはExcelの読み書きをpythonで行うためのモジュールになり、
・特定のセルに読み書きを行う
・シートを追加する
・グラフを追加する
などの処理が行えます。
※参考:https://rightcode.co.jp/blog/information-technology/python-openpyxl-excel-automatic-operation

openpyxlを利用するにあたり、下記でライブラリのインストールを行ってください。

pip install openpyxl

or

pip3 install openpyxl

これで準備完了です。
環境構築は簡単かつすぐに行えます。

■openpyxlで各セルにデータを書き込む

ではまずデータを書き込む方法に関してまとめていきます。

前提条件としてdataX, dataY変数を用いるのですが、
各データは下記とします。

dataX = ["index",1,2,3,4,5]
dataY = [
     ["data1",10,5,30,50,80],
     ["data2",100,5,30,10,100]
    ]

では全体のコードですが、下記となります。

def DataToXmlFiles(dataX, dataY, outfile):
    wb = Workbook()
    ws = wb.active

    for var in range(len(dataX)):
        ws.cell(row=var+1,column=1).value = dataX[var]
        for i in range(2):
            ws.cell(row=var+1, column=i+2).value = float(dataY[i][var])
    wb.save(outfile)

まず、

    wb = Workbook()
    ws = wb.active

にてセルの書き込むための新規シートを定義します。

後は、

ws.cell(row=var+1,column=1).value = values

といった形でrow,columnで挿入したいセル値を与えてvalueにセットしたい値や文字列を与えるだけです。
row、columnは左上から1,2,3~~になります。
今回先ほどのdataXをexcelシートのA列、dataYをB列、C列にセットしたかったので、

    for var in range(len(dataX)):
        ws.cell(row=var+1,column=1).value = dataX[var]
        for i in range(2):
            ws.cell(row=var+1, column=i+2).value = float(dataY[i][var])

といったような制御としました。
valueにセットするのは数値、文字列どちらでもセット可能です。
意識せずともセットすることが可能になっています。

最後に、

wb.save(outfile)

でエクセルファイルとして保存します。

■openpyxlでグラフを作成する

では次に先ほどセットしたセル値から自動でグラフを作成していきます。
コードはこちら。

def DataToXmlFiles(dataX, dataY, outfile):
    wb = Workbook()
    ws = wb.active

    for var in range(len(dataX)):
        ws.cell(row=var+1,column=1).value = dataX[var]
        for i in range(2):
            ws.cell(row=var+1, column=i+2).value = float(dataY[i][var])
    wb.save(outfile)

    #==========ここから追記==========
    values = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=len(dataX))
    categories = Reference(ws, min_col=1, min_row=2, max_col=1, max_row=len(dataX))

    chart = LineChart()

    chart.add_data(values, titles_from_data=True)
    chart.set_categories(categories)

    ws.add_chart(chart,"E1")
    #==========ここまで追記==========
    wb.save(outfile)

追加したコードは下記になります。

    values = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=len(dataX))
    categories = Reference(ws, min_col=1, min_row=2, max_col=1, max_row=len(dataX))

    chart = LineChart()

    chart.add_data(values, titles_from_data=True)
    chart.set_categories(categories)

    ws.add_chart(chart,"E1")

まず、

 values = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=len(dataX))

にてグラフとして作成グラフの各種(y列)をセットしていきます。
min_colやmin_rowには最小の行列値、
max_col、max_rowには最大の行列値をセットします。
要するに、
min_col ~ max_colで指定した範囲の列かつ、
min_row ~ max_rowで指定した範囲の行
に関してグラフを作成しますよ。
ということです。
今回はB、C列かつ5行になりますので、
min_col = 2 (Bから)、max_col=3(C列まで)
min_row = 1(1行目から)、max_row=len(dataX)(dataX要素数まで)
と定義しました。

categories = Reference(ws, min_col=1, min_row=2, max_col=1, max_row=len(dataX))

はX軸として指定する範囲になります。
指定の仕方は先ほどと同様なので割愛します。

後は、どんなグラフを用いるのかを

chart = LineChart()

で指定した後、

    chart.add_data(values, titles_from_data=True)
    chart.set_categories(categories)

にてシートにグラフをセットします。
ここで、
titles_from_data=True
を指定しますと、valuesで指定したデータの先頭1行目を系列名として用いることが出来ます。
逆に系列名は不要な場合には、

chart.legend = None

とすればOKです。

最後に、

ws.add_chart(chart,"E1")

にてグラフをシート上にセット。
セットする値は第2引数にセットすることが出来、今回は"E1"の位置にしました。

■実行結果

こちらのコードを実行すると下記のようなエクセルファイルが出力されます。
f:id:Elsammit:20210826231044p:plain

問題なくグラフ化とデータが書き込んでエクセル出力できました。

■最後に

今回は作業自動化のためにデータをエクセルに掃き出しかつグラフの作成まで自動化するためのコードを作成しました。
これはかなり便利なのでもう少しツールを使い込んでいこうと思います!!
どうやらパワーポイントも作れそうなのでこっちも調べてみようかな??