File size: 5,856 Bytes
217f8d7
decde83
 
 
217f8d7
 
 
89bee7d
217f8d7
 
decde83
217f8d7
 
 
 
 
 
 
 
 
decde83
217f8d7
3a5a6b0
217f8d7
decde83
217f8d7
 
 
decde83
 
217f8d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
decde83
217f8d7
 
 
 
 
 
 
 
 
 
 
 
 
3e2408a
217f8d7
 
 
 
 
 
 
 
 
 
3e2408a
 
217f8d7
 
 
 
 
 
 
 
 
 
 
3e2408a
217f8d7
 
 
 
 
 
3e2408a
 
217f8d7
 
c09e6b7
 
217f8d7
c09e6b7
 
217f8d7
c09e6b7
 
 
 
 
217f8d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c09e6b7
217f8d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import streamlit as st
import pandas as pd
import requests
import plotly.express as px
import matplotlib.font_manager as fm
import matplotlib as mpl
import io
import time
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# 確保正確的中文字符編碼
st.set_page_config(page_title="🌳台灣中小企業ESG數據分析與揭露儀表板🌲", page_icon=":chart_with_upwards_trend:", layout="wide")

# 定義 URL
urls = {
    "溫室氣體": "https://mopsfin.twse.com.tw/opendata/t187ap46_L_1.csv",
    "能源": "https://mopsfin.twse.com.tw/opendata/t187ap46_O_2.csv",
    "董事會揭露": "https://mopsfin.twse.com.tw/opendata/t187ap46_L_6.csv"
}

# 下載並載入 CSV 檔案到 DataFrame 的函數
@st.cache_data
def load_data(url):
    response = requests.get(url)
    response.encoding = 'utf-8'
    df = pd.read_csv(io.StringIO(response.text), encoding='utf-8')
    df = df.fillna(0)
    return df

# Streamlit 應用程式
st.title("台灣企業ESG數據分析與揭露")
st.subheader("以溫室氣體 X 再生能源 X 董事會資訊: https://www.tejwin.com/insight/carbon-footprint-verification/")
st.subheader("ESG投資: https://www.fhtrust.com.tw/ESG/operating")

# 允許用戶選擇數據集
dataset_choice = st.selectbox("選擇要顯示的數據集", list(urls.keys()))

# 載入選定的數據集
selected_df = load_data(urls[dataset_choice])

# 顯示爬取的資料
st.write("### 爬取的資料預覽")
st.dataframe(selected_df.head())

# 過濾出數值類型的欄位,排除 '出表日期' 和 '報告年度'
numeric_columns = selected_df.select_dtypes(include=['float64', 'int64']).columns
numeric_columns = [col for col in numeric_columns if col not in ['出表日期', '報告年度']]

# 允許用戶選擇用於繪製圖表的欄位
column_choice = st.selectbox("選擇欄位來繪製圖表", numeric_columns)

# 添加一個生成圖表的按鈕
if st.button("生成圖表"):
    # 顯示進度條
    progress_bar = st.progress(0)
    for i in range(100):
        time.sleep(0.01)
        progress_bar.progress(i + 1)

    # 創建一個標籤頁佈局
    tab1, tab2, tab3 = st.tabs(["圓餅圖", "長條圖", "K-means分析"])

    with tab1:
        # 使用 plotly 創建圓餅圖
        fig_pie = px.pie(
            selected_df,
            names='公司名稱',
            values=column_choice,
            title=f"{dataset_choice} - {column_choice} 圓餅圖",
            color_discrete_sequence=px.colors.qualitative.Pastel
        )
        fig_pie.update_traces(textposition='inside', textinfo='percent+label')
        fig_pie.update_layout(
            font=dict(size=12),
            legend=dict(
                orientation="h",
                yanchor="top",
                y=-0.3,
                xanchor="center",
                x=0.5
            ),
            height=700,
            margin=dict(t=50, b=50, l=50, r=50)
        )
        st.plotly_chart(fig_pie, use_container_width=True)

    with tab2:
        # 使用 plotly 創建長條圖
        fig_bar = px.bar(
            selected_df,
            x='公司名稱',
            y=column_choice,
            title=f"{dataset_choice} - {column_choice} 長條圖",
            color='公司名稱',
            color_discrete_sequence=px.colors.qualitative.Pastel
        )
        fig_bar.update_layout(
            xaxis_title="企業",
            yaxis_title=column_choice,
            font=dict(size=12),
            xaxis_tickangle=-45,
            showlegend=False,
            height=600
        )
        st.plotly_chart(fig_bar, use_container_width=True)

    with tab3:
        # 對所有數據集執行K-means分析
        st.subheader(f"{dataset_choice}數據的K-means分析")

        # 選擇用於聚類的特徵
        cluster_features = st.multiselect("選擇用於聚類的特徵", numeric_columns, default=numeric_columns[:2])

        # 選擇聚類數量
        n_clusters = st.slider("選擇聚類數量", min_value=2, max_value=10, value=3)

        # 添加一個執行K-means分析的按鈕
        if st.button("執行K-means分析"):
            if len(cluster_features) >= 2:
                # 準備數據
                X = selected_df[cluster_features]
                scaler = StandardScaler()
                X_scaled = scaler.fit_transform(X)

                # 執行K-means聚類
                kmeans = KMeans(n_clusters=n_clusters, random_state=42)
                clusters = kmeans.fit_predict(X_scaled)

                # 添加聚類結果到數據框
                selected_df['Cluster'] = clusters

                # 視覺化聚類結果
                fig_scatter = px.scatter(
                    selected_df,
                    x=cluster_features[0],
                    y=cluster_features[1],
                    color='Cluster',
                    hover_data=['公司名稱'],
                    title=f"{dataset_choice}數據的K-means聚類 ({cluster_features[0]} vs {cluster_features[1]})"
                )
                st.plotly_chart(fig_scatter, use_container_width=True)

                # 顯示每個聚類的特徵
                st.subheader("聚類特徵")
                cluster_stats = selected_df.groupby('Cluster')[cluster_features].mean()
                st.dataframe(cluster_stats)

            else:
                st.warning("請至少選擇兩個特徵進行聚類分析。")

    st.success("圖表生成完成!")

# 下載並設置自定義字體以顯示中文字符
font_url = "https://drive.google.com/uc?id=1eGAsTN1HBpJAkeVM57_C7ccp7hbgSz3_&export=download"
font_response = requests.get(font_url)
with open("TaipeiSansTCBeta-Regular.ttf", "wb") as font_file:
    font_file.write(font_response.content)
fm.fontManager.addfont("TaipeiSansTCBeta-Regular.ttf")
mpl.rc('font', family='Taipei Sans TC Beta')