Python:CSVファイルからグラフを生成してHTMLファイルに出力する(バージョンアップ版)
以前記事にした「Python:CSVファイルからグラフを生成してHTMLファイルに出力する」が意外と読まれているのでバージョンアップしました。
Pythonにて、以下の処理を行います。
事前準備:CSVファイルを任意のファイル名で作成します。
1.ファイルダイアログからCSVファイルを選択します。
→以前はCSVファイルの文字コードがUTF-8(BOM無)のみ可能でしたが、
Shift-JISも読み込めるようにしました。
2.グラフを生成します。
→以前はソース内でカラム位置を指定していましたが、
グラフ化出来そうな数値型が含まれている全てのカラムを
自動で判断してグラフ化するようにしました。
※折れ線グラフがおかしい場合は無視してください。
3.ファイルダイアログで出力するHTMLファイル名を入力して、
HTMLファイルに出力して、起動します。
→CSVファイルと同じフォルダに「CSVファイル名+日時.html」
で出力します。
CSVファイルのサンプルです
従業員ID,氏名,年齢,性別,郵便番号,住所,電話番号,メールアドレス,入社日,部署,役職,給与,勤務時間,有給休暇残日数,配偶者,子供人数,車両所有,資格1,資格2,社員ランク
1001,山田太郎,35,男性,100-0001,東京都千代田区大手町1-1-1,03-1234-5678,yamada_taro@example.com,2015-04-01,営業部,課長,5000000,9:00-18:00,10,未婚,0,あり,TOEIC,日商簿記2級,中堅社員
1002,佐藤花子,28,女性,100-0002,東京都千代田区霞が関2-2-2,03-2345-6789,sato_hanako@example.com,2018-07-15,人事部,主任,4000000,10:00-19:00,12,既婚,2,なし,TOEFL,情報処理技術者試験2級,中堅社員
1003,鈴木健太,42,男性,100-0003,東京都千代田区霞が関3-3-3,03-3456-7890,suzuki_kenta@example.com,2009-11-20,経理部,課長,5500000,9:30-18:30,15,既婚,1,なし,簿記1級,英検準1級,管理職
1004,田中真理,30,女性,100-0004,東京都千代田区霞が関4-4-4,03-4567-8901,tanaka_mari@example.com,2017-03-10,マーケティング部,リーダー,4500000,9:00-18:00,8,未婚,0,なし,TOEIC,情報処理技術者試験3級,中堅社員
1005,伊藤美香,38,女性,100-0005,東京都千代田区霞が関5-5-5,03-5678-9012,ito_mika@example.com,2012-08-05,営業部,マネージャー,6000000,9:30-18:30,18,既婚,3,あり,英検1級,情報処理技術者試験1級,管理職
1006,高橋健太郎,45,男性,100-0006,東京都千代田区霞が関6-6-6,03-6789-0123,takahashi_kentarou@example.com,2007-05-15,営業部,部長,7000000,9:00-18:00,20,既婚,2,なし,TOEIC,簿記1級,管理職
Pythonのソースサンプルです。
import pandas as pd
import plotly.express as px
import tkinter as tk
from tkinter import filedialog
import os
import webbrowser
import itertools
import datetime
from tqdm import tqdm
def select_file_dialog():
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
if not file_path:
print("CSVファイルが選択されませんでした。")
return file_path
def generate_html_filename(csv_file_path):
base_name = os.path.splitext(os.path.basename(csv_file_path))[0]
current_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
html_file_name = f"{base_name}_{current_time}.html"
return html_file_name
def read_csv_with_encoding(file_path):
try:
df = pd.read_csv(file_path, encoding='shift-jis')
except UnicodeDecodeError:
# Shift-JISで読み込めない場合はUTF-8で再試行
df = pd.read_csv(file_path, encoding='utf-8')
return df
def main():
# CSVファイルの選択
csv_file_path = select_file_dialog()
if not csv_file_path:
return
# CSVファイルの読み込み
df = read_csv_with_encoding(csv_file_path)
if df.empty:
print("CSVファイルが空です。")
return
print(df.info())
# グラフ生成
graphs = {
"折れ線グラフ": px.line,
"円グラフ": px.pie,
"棒グラフ": px.bar
}
figures = {}
for column in tqdm(df.columns, desc="グラフ生成中"):
figures[column] = {}
for graph_type, graph_func in graphs.items():
try:
if graph_type == "折れ線グラフ":
fig = graph_func(df, x=df.index, y=column, title=f"{column} - {graph_type}")
elif graph_type == "円グラフ":
fig = graph_func(df, values=column, names=df.index, title=f"{column} - {graph_type}")
else:
fig = graph_func(df, x=df.index, y=column, title=f"{column} - {graph_type}")
figures[column][graph_type] = fig
except Exception as e:
print(f"Error generating graph for {column} - {graph_type}: {e}")
continue
# HTMLファイルの保存場所を選択
html_file_name = generate_html_filename(csv_file_path)
output_file_path = os.path.join(os.path.dirname(csv_file_path), html_file_name)
# HTMLファイルにグラフを出力
with open(output_file_path, 'w', encoding='utf-8') as f:
f.write(f"<html><head><meta charset='utf-8'></head><body>")
for column, graph_types in figures.items():
for graph_type, fig in graph_types.items():
f.write(f"<h1>{column} - {graph_type}</h1>")
f.write(fig.to_html(full_html=False, include_plotlyjs='cdn'))
f.write("</body></html>")
print(f"グラフが{output_file_path}に保存されました。")
webbrowser.open(output_file_path)
if __name__ == "__main__":
main()
サンプルCSVをグラフ化した場合、以下のようになります。(全部は多いので一部抜粋)
この記事が気に入ったらサポートをしてみませんか?