File size: 9,527 Bytes
ee00e6a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9713fc8
ee00e6a
 
d0c82a3
 
 
 
 
 
ee00e6a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5e171c
 
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
import streamlit as st
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px

# Load data function
def load_data(uploaded_file):
    if uploaded_file is not None:
        df = pd.read_csv(uploaded_file)
        df.fillna(0, inplace=True)
        if '出表日期' in df.columns:
            df['出表日期'] = df['出表日期'].astype(str)
        if '公司代號' in df.columns:
            df['公司代號'] = df['公司代號'].astype(str)
        return df
    else:
        st.warning("請上傳檔案。")
        return None

# Merge dataframes
def merge_dataframes(df1, df2, on_columns):
    if df1 is None or df2 is None:
        return None
    for col in on_columns:
        if col in df1.columns and col in df2.columns:
            df1[col] = df1[col].astype(str)
            df2[col] = df2[col].astype(str)
    return pd.merge(df1, df2, on=on_columns, how="outer")

# Filter dataframe
def filter_dataframe(df, prefix):
    return df[df['公司代號'].astype(str).str.startswith(prefix)]

# Get specific company data
def get_specific_company(df, company_code):
    return df[df['公司代號'] == company_code]

# Plot radar chart
def plot_radar_chart(avg_values, specific_company_values, categories, prefix, specific_company_name):
    fig = go.Figure()

    fig.add_trace(go.Scatterpolar(
        r=avg_values,
        theta=categories,
        fill='toself',
        name=f"股號前兩位『{prefix}』的族群"
    ))

    fig.add_trace(go.Scatterpolar(
        r=specific_company_values,
        theta=categories,
        fill='toself',
        name=f'{specific_company_name}'
    ))

    fig.update_layout(
        polar=dict(radialaxis=dict(visible=True, range=[0, 100])),
        showlegend=True,
        title="董事會和投資人溝通指標比較"
    )

    st.plotly_chart(fig)

# Plot emission chart
def plot_emission_chart(filtered_df, avg_emissions, prefix):
    emission_columns = ['範疇一排放量(噸CO2e)', '範疇二排放量(噸CO2e)', '範疇三排放量(噸CO2e)']
    fig = go.Figure()

    for scope, color in zip(emission_columns, ['blue', 'green', 'red']):
        fig.add_trace(go.Bar(
            x=filtered_df['公司名稱'],
            y=filtered_df[scope],
            name=scope,
            marker_color=color
        ))

        fig.add_trace(go.Scatter(
            x=filtered_df['公司名稱'],
            y=[avg_emissions[scope]] * len(filtered_df),
            mode='lines',
            line=dict(color=color, dash='dash'),
            name=f'{scope}平均值'
        ))

    fig.update_layout(
        title=f"代號前兩位『{prefix}』的族群 - 各範疇排放量",
        barmode='group',
        xaxis_title="公司名稱",
        yaxis_title="排放量(噸CO2e)"
    )

    st.plotly_chart(fig)

# Plot energy usage
def plot_energy_usage(filtered_df, avg_energy_usage):
    fig_energy = px.bar(filtered_df, x='公司名稱', y='使用率(再生能源/總能源)', title="再生能源使用率")

    fig_energy.add_trace(go.Scatter(
        x=filtered_df['公司名稱'],
        y=[avg_energy_usage] * len(filtered_df),
        mode='lines',
        line=dict(color='red', dash='dash'),
        name='群體平均值'
    ))

    fig_energy.update_layout(
        yaxis_title="再生能源使用率 (%)",
        xaxis_title="公司名稱"
    )

    st.plotly_chart(fig_energy)
# Plot waste management box plots
def plot_waste_management(df_group, df_specific, company_name):
    columns_to_analyze = ['有害廢棄物量-數據(公噸)', '非有害廢棄物量-數據(公噸)', '總重量(有害+非有害)-數據(公噸)', '廢棄物密集度-密集度(公噸/單位)']

    fig = go.Figure()

    # Loop through the columns and plot box plot for each column
    for col in columns_to_analyze:
        fig.add_trace(go.Box(y=df_group[col], name=f'母群體-{col}', boxmean=True, boxpoints='outliers'))

        if not df_specific.empty:
            specific_value = df_specific[col].values[0]
            
            # Highlight specific company's value
            fig.add_trace(go.Scatter(
                y=[specific_value],
                x=[f'母群體-{col}'],
                mode='markers',
                name=f'{company_name}-{col}',
                marker=dict(color='red', size=11, symbol='star'),
                showlegend=True,
                hovertext=f'公司名稱: {company_name}, 值: {specific_value}'
            ))

    # Update layout
    fig.update_layout(
        title=f"廢棄物統計數據箱型圖 (包含指定公司名稱 {company_name} 數據)",
        yaxis_title="數值 (公噸)",
        xaxis_title="廢棄物項目",
        boxmode='group'
    )

    # Display the plot in Streamlit
    st.plotly_chart(fig)

    
# Main function update
def main():
    st.title("ESG analytic dashboard")
    
    # File upload
    st.sidebar.header("上傳CSV檔案- https://reurl.cc/yvAEql")
    investor_file = st.sidebar.file_uploader("上傳【投資人溝通】.csv", type=["csv"])
    board_file = st.sidebar.file_uploader("上傳【董事會】.csv", type=["csv"])
    emission_file = st.sidebar.file_uploader("上傳【溫室氣體排放】.csv", type=["csv"])
    energy_file = st.sidebar.file_uploader("上傳【能源管理】.csv", type=["csv"])
    waste_file = st.sidebar.file_uploader("上傳【廢棄物管理】.csv", type=["csv"])

    # Load data
    investor_df = load_data(investor_file)
    board_df = load_data(board_file)
    emission_df = load_data(emission_file)
    energy_df = load_data(energy_file)
    waste_df = load_data(waste_file)

    # Merge data
    merged_df1 = merge_dataframes(investor_df, board_df, ["公司代號", "公司名稱", "出表日期", "報告年度"])
    merged_df2 = merge_dataframes(emission_df, energy_df, ["公司代號", "公司名稱", "出表日期", "報告年度"])

    # User input
    prefix = st.sidebar.text_input("輸入公司代號前兩位")
    specific_company_code = st.sidebar.text_input("輸入四位數字公司代號")

    # Waste management analysis
    if waste_df is not None and prefix:
        waste_df['公司代號前兩位'] = waste_df['公司代號'].astype(str).str[:2]
        df_group = waste_df[waste_df['公司代號前兩位'] == prefix]
        df_specific = waste_df[waste_df['公司代號'] == specific_company_code]

        if not df_specific.empty:
            company_name = df_specific['公司名稱'].values[0]
            plot_waste_management(df_group, df_specific, company_name)
        else:
            st.warning(f"找不到公司代號為 {specific_company_code} 的廢棄物管理數據")



    # Handle 投資人溝通和董事會資料
    if merged_df1 is not None and prefix and specific_company_code:
        columns_of_interest = ['董事出席董事會出席率', '董事進修時數符合進修要點比率', '公司年度召開法說會次數(次)']
        for col in ['董事出席董事會出席率', '董事進修時數符合進修要點比率']:
            merged_df1[col] = merged_df1[col].replace({'%': ''}, regex=True).astype(float)

        filtered_df1 = filter_dataframe(merged_df1, prefix)
        avg_values = filtered_df1[columns_of_interest].mean()
        specific_company_df1 = get_specific_company(merged_df1, specific_company_code)

        if not specific_company_df1.empty:
            specific_company_name = specific_company_df1['公司名稱'].iloc[0]
            specific_company_values = specific_company_df1[columns_of_interest].iloc[0]
            plot_radar_chart(avg_values, specific_company_values, ['董事出席率', '董事進修時數符合比率', '年度法說會次數'], prefix, specific_company_name)
        else:
            st.warning(f"找不到公司代號 {specific_company_code} 的資料")

    # Handle 溫室氣體排放和能源管理資料
    if merged_df2 is not None and prefix:
        emission_columns = ['範疇一排放量(噸CO2e)', '範疇二排放量(噸CO2e)', '範疇三排放量(噸CO2e)']
        energy_column = '使用率(再生能源/總能源)'
        merged_df2[energy_column] = merged_df2[energy_column].replace({'%': ''}, regex=True).astype(float)

        filtered_df2 = filter_dataframe(merged_df2, prefix)
        specific_company_df2 = get_specific_company(merged_df2, specific_company_code)

        if not filtered_df2.empty:
            avg_emissions = filtered_df2[emission_columns].mean()
            plot_emission_chart(filtered_df2, avg_emissions, prefix)

            avg_energy_usage = filtered_df2[energy_column].mean()
            plot_energy_usage(filtered_df2, avg_energy_usage)

            if not specific_company_df2.empty:
                specific_energy_usage = specific_company_df2[energy_column].iloc[0]
                comparison_data = {
                    '公司名稱': [specific_company_df2['公司名稱'].iloc[0], f"{prefix} 母群體平均"],
                    '再生能源使用率 (%)': [specific_energy_usage, avg_energy_usage]
                }
                comparison_df = pd.DataFrame(comparison_data)
                st.write("\n再生能源使用率比較表格:")
                st.write(comparison_df)
            else:
                st.warning(f"找不到公司代號 {specific_company_code} 的能源管理數據")
        else:
            st.warning(f"找不到前兩碼為 {prefix} 的公司數據")

if __name__ == "__main__":
    main()

# https://drive.google.com/drive/folders/1uZnryIluMn-bszuHsFMbLecbL6Vq3HyI?usp=sharing