見出し画像

財務データの可視化とインタラクティブなダッシュボード構築 - Day 5

これまでに整備した財務データを可視化し、インタラクティブなダッシュボードを構築していきます。StreamlitとPlotlyを使って、誰でも簡単に財務分析ができる環境を作ります。

メインの処理フロー

  1. データの流れ

    • BigQueryからの財務データ取得(月次収益・経費データ)

    • Pandasデータフレームへの変換と加工(利益・利益率の計算)

    • 部門別・月次での集計処理

  2. 画面構成の生成(StreamlitとPlotly)

    • ダッシュボードタイトル表示

    • 部門別メトリクス表示(総収益・総利益・利益率)

    • トレンドチャート生成(Plotlyによる可視化)

    • 部門間相関ヒートマップ生成

    • 詳細データテーブル(オプション表示)

Streamlitの特徴

Pythonスクリプトを直接Webアプリケーション化できるフレームワークです。コードの実行順序がそのままUI要素の配置順序になり、直感的な開発が可能です。

環境準備

pip install streamlit plotly pandas google-cloud-bigquery

プログラム一式

import streamlit as st
import plotly.express as px
import plotly.graph_objects as go
from google.cloud import bigquery
from google.oauth2 import service_account
import pandas as pd
from datetime import datetime, timedelta

# BigQuery設定
credentials = service_account.Credentials.from_service_account_file('your-key.json')
client = bigquery.Client(credentials=credentials, project='taki-sample001-202402')

def load_data():
    """財務データの読み込み"""
    query = """
    WITH monthly_summary AS (
        SELECT
            DATE_TRUNC(accounting_date, MONTH) as month,
            department_name,
            SUM(CASE 
                WHEN credit_account LIKE '5%' THEN amount
                WHEN debit_account LIKE '5%' THEN -amount
                ELSE 0
            END) as revenue,
            SUM(CASE 
                WHEN debit_account LIKE '6%' THEN -amount
                WHEN credit_account LIKE '6%' THEN amount
                ELSE 0
            END) as expenses
        FROM `accounting.journal_entries`
        GROUP BY 1, 2
    )
    SELECT *,
           revenue + expenses as profit,
           CASE WHEN revenue != 0 
                THEN ROUND((revenue + expenses) / revenue * 100, 2)
                ELSE 0 
           END as profit_margin
    FROM monthly_summary
    ORDER BY month, department_name
    """
    return client.query(query).to_dataframe()

def create_department_metrics():
    """部門別メトリクスの表示"""
    st.subheader("部門別業績サマリー")
    
    # 部門選択
    selected_dept = st.selectbox(
        "部門を選択してください",
        df['department_name'].unique()
    )
    
    # 選択部門のデータ
    dept_data = df[df['department_name'] == selected_dept].copy()
    
    # メトリクス表示
    col1, col2, col3 = st.columns(3)
    with col1:
        total_revenue = dept_data['revenue'].sum()
        st.metric("総収益", f"¥{total_revenue:,.0f}")
    with col2:
        total_profit = dept_data['profit'].sum()
        st.metric("総利益", f"¥{total_profit:,.0f}")
    with col3:
        avg_margin = dept_data['profit_margin'].mean()
        st.metric("平均利益率", f"{avg_margin:.1f}%")

def create_trend_chart():
    """トレンドチャートの作成"""
    st.subheader("月次推移")
    
    # グラフ種類の選択
    metric = st.radio(
        "表示する指標を選択してください",
        ["revenue", "profit", "profit_margin"],
        format_func=lambda x: {
            "revenue": "収益",
            "profit": "利益",
            "profit_margin": "利益率"
        }[x]
    )
    
    # Plotlyでグラフ作成
    fig = px.line(
        df,
        x='month',
        y=metric,
        color='department_name',
        title="月次推移分析"
    )
    
    fig.update_layout(
        xaxis_title="月",
        yaxis_title="金額(円)" if metric != "profit_margin" else "利益率(%)",
        legend_title="部門"
    )
    
    st.plotly_chart(fig, use_container_width=True)

def create_heatmap():
    """部門間相関ヒートマップの作成"""
    st.subheader("部門間相関分析")
    
    # 部門別の月次データをピボット
    pivot_df = df.pivot(
        index='month',
        columns='department_name',
        values='profit'
    )
    
    # 相関係数計算
    corr = pivot_df.corr()
    
    # ヒートマップ作成
    fig = go.Figure(data=go.Heatmap(
        z=corr,
        x=corr.columns,
        y=corr.columns,
        colorscale='RdBu',
        zmin=-1,
        zmax=1
    ))
    
    fig.update_layout(
        title="部門間の利益相関",
        height=500
    )
    
    st.plotly_chart(fig, use_container_width=True)

def main():
    st.title("財務分析ダッシュボード")
    
    global df
    df = load_data()
    
    create_department_metrics()
    create_trend_chart()
    create_heatmap()
    
    # データテーブル表示(オプション)
    if st.checkbox("詳細データを表示"):
        st.dataframe(df)

if __name__ == "__main__":
    main()

実行方法

streamlit run finance_dashboard.py

主要機能の実装解説

データ読み込み(load_data関数)

BigQueryから取得したデータを加工し、分析に必要な指標を計算します。このデータが他の全ての表示の基礎となります。

  • WITH句で月次サマリーを作成し、1回のクエリで効率的にデータ取得

  • CASE文で収益・費用を正負で区別

  • 計算済み指標(利益率など)もSQLで事前計算

部門別メトリクス(create_department_metrics関数)

選択された部門の主要な財務指標をダッシュボード形式で表示します。直感的な部門パフォーマンスの把握が可能です。

  • st.selectboxで部門選択UIを実装

  • st.columns(3)で3カラムレイアウトを構成

  • st.metricで指標を視覚的に表示

  • f文字列でフォーマット(通貨表示)

トレンドチャート(create_trend_chart関数)

時系列での推移を可視化し、部門間の比較や傾向分析を可能にします。

  • st.radioで指標切り替えを実装

  • Plotly Expressで対話的グラフ生成

  • format_funcで表示名を日本語化

  • カラーコーディングで部門を区別

相関ヒートマップ(create_heatmap関数)

部門間の関係性を視覚化し、事業構造の理解を深めることができます。

  • pandas.pivotでデータ形式を変換

  • corr()で相関係数を計算

  • Plotly.go.Heatmapで可視化

  • RdBu(赤青)カラースケールで相関を表現

まとめと次のステップ

今回の実装により、財務データの動的な分析が可能になりました。明日は財務指標の自動計算と分析レポート生成機能を実装していきます。

#Python #Streamlit #DataVisualization #FinancialAnalysis #AdventCalendar

いいなと思ったら応援しよう!