File size: 4,556 Bytes
579e6f3
 
 
 
df41ada
 
7001d25
 
579e6f3
7001d25
 
3b4db15
 
 
7001d25
3b4db15
579e6f3
7001d25
 
 
 
 
 
 
 
 
 
 
 
 
 
3b4db15
7001d25
 
 
17a30d8
7001d25
 
 
 
 
 
 
3b4db15
7001d25
 
 
9016aeb
7001d25
98655f8
7001d25
 
 
 
 
 
 
 
 
 
 
 
5b8748d
7001d25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import pandas as pd
import requests
import plotly.express as px
import io

# 設置顏色主題
theme = px.colors.qualitative.Bold

# 下載並載入 CSV 數據
def download_and_load_csv(url):
    response = requests.get(url)
    response.encoding = 'utf-8'
    df = pd.read_csv(io.StringIO(response.text), encoding='utf-8')
    df = df.fillna(0)  # 避免 NaN 錯誤
    return df

# 美化圖表
def beautify_chart(fig):
    fig.update_layout(
        font_family="Arial",
        font_color="#444",
        title_font_family="Arial",
        title_font_color="#000",
        legend_title_font_color="#000",
        plot_bgcolor='rgba(0,0,0,0)',
        paper_bgcolor='rgba(0,0,0,0)',
    )
    fig.update_xaxes(showline=True, linewidth=2, linecolor='lightgray', gridcolor='lightgray')
    fig.update_yaxes(showline=True, linewidth=2, linecolor='lightgray', gridcolor='lightgray')
    return fig

# **生成 Plotly 圖表**
def generate_plots(df, df_name, selected_columns, chart_type):
    selected_columns = list(selected_columns)  # 確保是列表

    if not selected_columns:
        st.error("❌ 沒有選擇數據欄位,請至少選擇一個!")
        return
    
    if "公司名稱" not in df.columns:
        st.error("❌ 缺少 公司名稱 欄位,請確認數據格式!")
        return

    # ✅ **確保所有 y 軸數據與 x 軸 (公司名稱) 長度一致**
    df = df.dropna(subset=["公司名稱"] + selected_columns)  # **移除 NaN 確保長度相同**
    df[selected_columns] = df[selected_columns].apply(pd.to_numeric, errors='coerce')  # **轉換數據類型**
    
    valid_columns = [col for col in selected_columns if col in df.columns and len(df[col]) == len(df["公司名稱"])]
    
    if not valid_columns:
        st.error(f"❌ 選擇的欄位長度與 公司名稱 不匹配,請檢查數據!\n"
                 f"📊 公司名稱 長度: {len(df['公司名稱'])}\n"
                 f"🟢 可用欄位: {valid_columns}")
        return

    with st.expander(f"📊 顯示 {df_name} 圖表"):
        st.subheader(f"{df_name} - {chart_type} 圖")

        # **根據選擇的圖表類型來繪製**
        if chart_type == "折線圖":
            fig = px.line(df, x="公司名稱", y=valid_columns, title=f"{df_name} - 折線圖", color_discrete_sequence=theme)
        
        elif chart_type == "散點圖":
            fig = px.scatter(df, x="公司名稱", y=valid_columns, title=f"{df_name} - 散點圖", color_discrete_sequence=theme)
        
        elif chart_type == "長條圖":
            fig = px.bar(df, x="公司名稱", y=valid_columns, title=f"{df_name} - 長條圖", color_discrete_sequence=theme)
        
        elif chart_type == "餅圖":
            total_emissions = df.groupby("公司名稱")[valid_columns].sum().reset_index()
            total_emissions = total_emissions.melt(id_vars=["公司名稱"], value_vars=valid_columns, var_name="排放類型", value_name="總排放量")
            fig = px.pie(total_emissions, values='總排放量', names='公司名稱', title=f"{df_name} - 餅圖", color_discrete_sequence=theme, hole=0.3)
            fig.update_traces(textposition='inside', textinfo='percent+label')

        fig = beautify_chart(fig)
        st.plotly_chart(fig, use_container_width=True)  # ✅ **讓圖表自適應畫面**

# **下載數據**
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"
]

dfs = [download_and_load_csv(url) for url in urls]
combined_df = pd.concat(dfs, ignore_index=True).fillna(0)  # 合併數據並填充 NaN 值

# **再次填充 NaN 值**
combined_df = combined_df.fillna(0)

# **只顯示前300筆數據**
combined_df = combined_df.head(300)

# **Streamlit UI**
st.title("📊 台灣企業 ESG 數據分析")

st.subheader("📂 數據預覽")
st.dataframe(combined_df)

# **選擇數據欄位**
emission_columns = ["範疇一排放量(噸CO2e)", "範疇二排放量(噸CO2e)", "範疇三排放量(噸CO2e)"]
selected_columns = st.multiselect("選擇要顯示的排放類別", emission_columns, default=emission_columns[:1])

# **選擇圖表類型**
chart_type = st.selectbox("選擇圖表類型", ["折線圖", "散點圖", "長條圖", "餅圖"])

# **生成圖表**
if selected_columns:
    generate_plots(combined_df, "綜合數據", selected_columns, chart_type)
else:
    st.write("⚠️ 請選擇至少一個排放類別來顯示圖表。")