機械系エンジニアの備忘録

20代独身社会人。仕事では機械・機構の研究開発を行っているエンジニアが、自分の専門分野ではないpythonを扱って楽しむブログです。

MENU

【python】【初心者】Tkinterとopenpyxlを使ってCSVの中身を抽出し散布図付きのExcelを自動作成する方法

Tkinterとopenpyxlの使い方

2020/01/26追記:プログラミング初心者に向けたpythonの勉強法と手順を記事にしました。

stjun.hatenablog.com

 

■はじめに

以前、

tkinterを用いてGUIからCSVファイルを選び、

②選んだCSVファイル内の数値データを抽出してExcelシートに書き込み、

③新規Excelファイルとして保存する一連の流れを紹介しました。

 

stjun.hatenablog.com

stjun.hatenablog.com

stjun.hatenablog.com

 また上記を拡張して複数のCSVを同時に処理する方法も紹介しました。

stjun.hatenablog.com

今回この続きになります。

本記事では、グラフ(今回は散布図)も自動で作成する方法を紹介します。

 

■コード

#1つのExcel作成、散布図作成
import tkinter as tk
import tkinter.filedialog as fl
import numpy as np
import time
import openpyxl as px
from openpyxl.chart import ScatterChart,Reference,Series

root=tk.Tk()

#ファイルパスをマウスで選ぶ
#ユーザー名にお使いのPCの名前を入れてください
def get(*args):
    filetype=[("all file","*")]    
    path=fl.askopenfilename(initialdir="C:/Users/ユーザー名/Desktop",filetypes=filetype,title="ファイルを選んでください")
    message["text"]=path
    
    #CSVファイルのデータを読み込み表示させる
    data_1, data_2,data_3= np.loadtxt(fname=path, skiprows=2, unpack=True)
    
    #今日の日付・時間を取得(ファイル名に入れるため)
    timestr=time.strftime("%Y%m%d-%H%M%S") #年月日時分秒の形式で取得

    #新しいExcelの作成とアクティブ化
    wb=px.Workbook()
    ws=wb.active

    #Excelシートの名前を設定
    ws.title="計算結果"

    #Excel一行目にどんな物理量について計算したか記載するためのリスト
    list_target=["x軸","物理量A(単位)","物理量B(単位)"]

    #Excelの1行目に記載していく
    for i in range(len(list_target)):
        ws.cell(row=1,column=i+1,value=list_target[i])

    #計算結果をセルに代入する
    for i in range(len(data_1)):
        ws.cell(row=i+2,column=1,value=data_1[i])
        ws.cell(row=i+2,column=2,value=data_2[i])
        ws.cell(row=i+2,column=3,value=data_3[i])
    
    #グラフとして散布図を作成する
    chart =ScatterChart()
    #グラフのタイトル
    chart.title = "散布図のテスト"
    #x軸のタイトル
    chart.x_axis.title = 'x軸'
    #y軸のタイトル
    chart.y_axis.title = 'y軸'

    #x軸とするデータ
    x_values = Reference(ws, min_col=1, min_row=2, max_row=len(data_1)+1)
    for i in range(2, 4):
        #y軸とするデータ
        y_values = Reference(ws, min_col=i, min_row=1, max_row=len(data_1)+1)
        #x軸とy軸の組み合わせを決める
        con = Series(y_values, x_values, title_from_data=True)
        #マーカーの形
        con.marker.symbol = 'circle' 
        #マーカーの塗りつぶし
        con.marker.graphicalProperties.solidFill ="FFFFFF"
        #マーカーの枠線の色
        con.marker.graphicalProperties.line.solidFill = "000000"
        #散布図に系列を追加
        chart.series.append(con)

    #シートにグラフを追加
    ws.add_chart(chart, "A10")

    #Excelデータをデスクトップに保存する(ユーザー名にお使いのPCの名前を入れてください)
    wb.save(r"/Users/ユーザー名/Desktop/test"+timestr+".xlsx")

message=tk.Label(root,text="ファイルを選択してください",width=30)
message.grid(row=0,column=0)

button=tk.Button(text="開く",command=get)
button.grid(row=0,column=1)

root.mainloop()

コードを実行すると、いつものように次の画面がでてきます。

f:id:stjun:20190812143311p:plain

右側の開くボタンを押すと選択画面がでてきます。今回はデスクトップに置いてある「data_test.csv」を開きます、またdata_test.csvは右画面にように上から2行目までは説明文で、3行目から数値データが始まるファイルとします。(実験データを意識してます)

f:id:stjun:20190812143600p:plain

 

開くを押すとデスクトップにファイル名が作成日のExcelファイルが作成されます。開くと次のような画面になります。ちゃんとセルにデータが格納されており、また散布図が自動で作成されたのが確認できます。

f:id:stjun:20190812160639p:plain

 以上で終わりです。

散布図が自動で作成できると、いちいち1つ1つグラフを作成する必要がなくなるので大幅な時短になりそうです。

■説明

まず必要なモジュールをインポートしましょう。特にopenpyxlでグラフも作成したい場合、次の2行は必須です。(グラフを作成するつもりがないなら1行目だけでOKです)

import openpyxl as px
from openpyxl.chart import ScatterChart,Reference,Series

ここでScatterChartとは散布図のことです。例えば棒グラフの場合はBarChartとします。以下に主要なグラフの名前を挙げておきます。

  • 散布図:ScatterChart
  • 棒グラフ:BarChart
  • 折れ線グラフ:LineChart
  • 円グラフ:PieChart
  • レーダーチャート:RadarChart

になります。それ以外にも3D図なども書けます。

 

次にグラフの作成に入ります。

    #グラフとして散布図を作成する
    chart =ScatterChart()
    #グラフのタイトル
    chart.title = "散布図のテスト"
    #x軸のタイトル
    chart.x_axis.title = 'x軸'
    #y軸のタイトル
    chart.y_axis.title = 'y軸'

1行目ではchartという変数に散布図ScatterChart()を代入しています。

2行目はグラフのタイトルになります。

3行目と4行目は軸のタイトルになります。例えばx軸が時間でy軸を距離にしたい場合は、3行目に時間[s]、4行目に距離[m]と入れてください。

 

次にデータを入れていきます。

#x軸とするデータ
    x_values = Reference(ws, min_col=1, min_row=2, max_row=len(data_1)+1)
    for i in range(2, 4):
        #y軸とするデータ
        y_values = Reference(ws, min_col=i, min_row=1, max_row=len(data_1)+1)
        #x軸とy軸の組み合わせを決める
        con = Series(y_values, x_values, title_from_data=True)
        #マーカーの形
        con.marker.symbol = 'circle' 
        #マーカーの塗りつぶし
        con.marker.graphicalProperties.solidFill ="FFFFFF"
        #マーカーの枠線の色
        con.marker.graphicalProperties.line.solidFill = "000000"
        #散布図に系列を追加
        chart.series.append(con)

まず1行目ではグラフのx軸のデータを何にするかを決めています。

 #x軸とするデータ
    x_values = Reference(ws, min_col=1, min_row=2, max_row=len(data_1)+1)

カッコ内のwsは最初の方に書いた次の変数wsになります。つまり今作ったExcelシートを参照するよっという意味になります。min_col=1はシートの1列目を参照するという意味です。min_row=2, max_row=len(data_1)+1)は2行目から7行目(len(data_1)=6なので)まで参照するという意味になります。

    #新しいExcelの作成とアクティブ化
    wb=px.Workbook()
    ws=wb.active

また次のy軸とするデータも書き方はx軸と全く同じです。1つだけ違うのはmin_row=1になっていることです。つまり1行目も参照するということです。1行目は数値ではなく文字が書かれています。後で紹介しますがここで1行目の文字まで含めておくことで、グラフのタイトルを自動で入れることができます。

        #y軸とするデータ
        y_values = Reference(ws, min_col=i, min_row=1, max_row=len(data_1)+1)

次に、グラフのx軸をy軸の組み合わせを決めます。Series(y軸にしたい値、x軸にしたい値)の順に書きます。最後のtitle_from_data=Trueにすると、先ほどy軸のデータを決めるとき含めた1行目の文字がグラフ名として自動で設定されます。今回2列目1行目は物理量A(単位)としているので、図の右側のハイライトした部分が物理量A(単位)になっています。

        #x軸とy軸の組み合わせを決める
        con = Series(y_values, x_values, title_from_data=True)

f:id:stjun:20190812160709p:plain

次にマーカーの形などを決めていきます。ここは任意です、なくても構いません。

        #マーカーの形=円にする
        con.marker.symbol = 'circle' 
        #マーカーの塗りつぶし=白で塗りつぶし
        con.marker.graphicalProperties.solidFill ="FFFFFF"
        #マーカーの枠線の色=黒色にする
        con.marker.graphicalProperties.line.solidFill = "000000"

次にグラフをシートに追加します。

今回はセルA10の位置からグラフを表示しました。

    #シートにグラフを追加
    ws.add_chart(chart, "A10")

以上が1つの列(今回は2列目)をグラフ化する方法です。今回3列目にもデータがあるのでfor文を使って2列目と3列目のグラフを作成しています。

 

■自分が使ってるお得情報の紹介

私はAmazon kindle unlimitedというサービスを1年以上利用しています。

これは月額980円で 和書12万冊以上の電子書籍を読めるサービスです。

ビジネス本、雑誌、漫画、技術本など様々な本を読むことができます。10冊まで端末にダウンロードできるのでネット環境がなくても(オフラインでも)見れます。

なおkindle unlimitedは最初の30日間無料のため、気軽に登録してみて、あまり読みたい本が無ければすぐに解約しても問題ありません。

それか30日内に気になる本を全て読破すれば実質タダです。

ぜひ気になった方はチェックしてみて下さい。

なおkindleにない本等を買う時はamazonギフト券(amazonで使えるポイント)を買い、ポイントで数冊まとめて買った方がお得です。

ギフト券(ポイント)は買ったら10年も有効で、ポイントが付きます。さらに本をまとめ買い(2冊以上同時に)買うと、ポイントがもらえます。

https://www.amazon.co.jp/b?ie=UTF8&node=5431437051

学生さんであればkindle unlimitedよりも年2450円(月210円程度)で映画見放題、音楽聞き放題、本読み放題の「prime student」がおすすめです。

以下に私がkindle unlimitedで読んだ本を載せておきます。

さおだけ屋はなぜ潰れないのか? 身近な疑問からはじめる会計学 (光文社新書)

さおだけ屋はなぜ潰れないのか? 身近な疑問からはじめる会計学 (光文社新書)

  • 作者:山田 真哉
  • 出版社/メーカー: 光文社
  • 発売日: 2005/02/16
  • メディア: 新書
 
多動力 (NewsPicks Book) (幻冬舎文庫)

多動力 (NewsPicks Book) (幻冬舎文庫)

 

 

■雑誌系

 

MONOQLO (モノクロ) 2020年 02月号 [雑誌]

MONOQLO (モノクロ) 2020年 02月号 [雑誌]

 
家電批評 2020年 1月号 [雑誌]

家電批評 2020年 1月号 [雑誌]

  • 作者: 
  • 出版社/メーカー: 晋遊舎
  • 発売日: 2019/12/03
  • メディア: Kindle
 
ロードバイク完全メンテナンス (エイムック 3544 BiCYCLE CLUB別冊)

ロードバイク完全メンテナンス (エイムック 3544 BiCYCLE CLUB別冊)

  • 作者: 
  • 出版社/メーカー: エイ出版社
  • 発売日: 2016/11/29
  • メディア: ムック
 
繰り返し作りたくなる!  ラク弁当レシピ (エイムック 3680)

繰り返し作りたくなる! ラク弁当レシピ (エイムック 3680)

 
Tarzan(ターザン) 2020年1月23日号 No.779 [内臓脂肪 皮下脂肪すっきり落とす!] [雑誌]

Tarzan(ターザン) 2020年1月23日号 No.779 [内臓脂肪 皮下脂肪すっきり落とす!] [雑誌]

  • 作者: 
  • 出版社/メーカー: マガジンハウス
  • 発売日: 2020/01/04
  • メディア: Kindle
 
DIME(ダイム) 2020年 03 月号 [雑誌]

DIME(ダイム) 2020年 03 月号 [雑誌]

  • 作者: 
  • 出版社/メーカー: 小学館
  • 発売日: 2019/12/16
  • メディア: 雑誌
 

 

■最後に

今回、CSVからデータを抽出するだけでなく、散布図も自動で作成する方法を紹介しました。ただグラフのデザイン等も指定できればより便利になりそうなので、今度紹介できればと思います。

またその他のグラフ等についてもopenpyxlの公式サイトに記載されています。リンクを張って良いのかわからないので張りませんが、気になる方はグーグルで調べるとすぐ出てくるので見てみて下さい。英語のサイトですが、chromeで開けば自動翻訳できるのでそこまで苦労しないと思います。

次記事

stjun.hatenablog.com