Spencer525 commited on
Commit
ee00e6a
·
verified ·
1 Parent(s): c615598

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +237 -0
app.py ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.graph_objects as go
4
+ import plotly.express as px
5
+
6
+ # Load data function
7
+ def load_data(uploaded_file):
8
+ if uploaded_file is not None:
9
+ df = pd.read_csv(uploaded_file)
10
+ df.fillna(0, inplace=True)
11
+ if '出表日期' in df.columns:
12
+ df['出表日期'] = df['出表日期'].astype(str)
13
+ if '公司代號' in df.columns:
14
+ df['公司代號'] = df['公司代號'].astype(str)
15
+ return df
16
+ else:
17
+ st.warning("請上傳檔案。")
18
+ return None
19
+
20
+ # Merge dataframes
21
+ def merge_dataframes(df1, df2, on_columns):
22
+ if df1 is None or df2 is None:
23
+ return None
24
+ for col in on_columns:
25
+ if col in df1.columns and col in df2.columns:
26
+ df1[col] = df1[col].astype(str)
27
+ df2[col] = df2[col].astype(str)
28
+ return pd.merge(df1, df2, on=on_columns, how="outer")
29
+
30
+ # Filter dataframe
31
+ def filter_dataframe(df, prefix):
32
+ return df[df['公司代號'].astype(str).str.startswith(prefix)]
33
+
34
+ # Get specific company data
35
+ def get_specific_company(df, company_code):
36
+ return df[df['公司代號'] == company_code]
37
+
38
+ # Plot radar chart
39
+ def plot_radar_chart(avg_values, specific_company_values, categories, prefix, specific_company_name):
40
+ fig = go.Figure()
41
+
42
+ fig.add_trace(go.Scatterpolar(
43
+ r=avg_values,
44
+ theta=categories,
45
+ fill='toself',
46
+ name=f"股號前兩位『{prefix}』的族群"
47
+ ))
48
+
49
+ fig.add_trace(go.Scatterpolar(
50
+ r=specific_company_values,
51
+ theta=categories,
52
+ fill='toself',
53
+ name=f'{specific_company_name}'
54
+ ))
55
+
56
+ fig.update_layout(
57
+ polar=dict(radialaxis=dict(visible=True, range=[0, 100])),
58
+ showlegend=True,
59
+ title="董事會和投資人溝通指標比較"
60
+ )
61
+
62
+ st.plotly_chart(fig)
63
+
64
+ # Plot emission chart
65
+ def plot_emission_chart(filtered_df, avg_emissions, prefix):
66
+ emission_columns = ['範疇一排放量(噸CO2e)', '範疇二排放量(噸CO2e)', '範疇三排放量(噸CO2e)']
67
+ fig = go.Figure()
68
+
69
+ for scope, color in zip(emission_columns, ['blue', 'green', 'red']):
70
+ fig.add_trace(go.Bar(
71
+ x=filtered_df['公司名稱'],
72
+ y=filtered_df[scope],
73
+ name=scope,
74
+ marker_color=color
75
+ ))
76
+
77
+ fig.add_trace(go.Scatter(
78
+ x=filtered_df['公司名稱'],
79
+ y=[avg_emissions[scope]] * len(filtered_df),
80
+ mode='lines',
81
+ line=dict(color=color, dash='dash'),
82
+ name=f'{scope}平均值'
83
+ ))
84
+
85
+ fig.update_layout(
86
+ title=f"代號前兩位『{prefix}』的族群 - 各範疇排放量",
87
+ barmode='group',
88
+ xaxis_title="公司名稱",
89
+ yaxis_title="排放量(噸CO2e)"
90
+ )
91
+
92
+ st.plotly_chart(fig)
93
+
94
+ # Plot energy usage
95
+ def plot_energy_usage(filtered_df, avg_energy_usage):
96
+ fig_energy = px.bar(filtered_df, x='公司名稱', y='使用率(再生能源/總能源)', title="再生能源使用率")
97
+
98
+ fig_energy.add_trace(go.Scatter(
99
+ x=filtered_df['公司名稱'],
100
+ y=[avg_energy_usage] * len(filtered_df),
101
+ mode='lines',
102
+ line=dict(color='red', dash='dash'),
103
+ name='群體平均值'
104
+ ))
105
+
106
+ fig_energy.update_layout(
107
+ yaxis_title="再生能源使用率 (%)",
108
+ xaxis_title="公司名稱"
109
+ )
110
+
111
+ st.plotly_chart(fig_energy)
112
+ # Plot waste management box plots
113
+ def plot_waste_management(df_group, df_specific, company_name):
114
+ columns_to_analyze = ['有害廢棄物量-數據(公噸)', '非有害廢棄物量-數據(公噸)', '總重量(有害+非有害)-數據(公噸)', '廢棄物密集度-密集度(公噸/單位)']
115
+
116
+ fig = go.Figure()
117
+
118
+ # Loop through the columns and plot box plot for each column
119
+ for col in columns_to_analyze:
120
+ fig.add_trace(go.Box(y=df_group[col], name=f'母群體-{col}', boxmean=True, boxpoints='outliers'))
121
+
122
+ if not df_specific.empty:
123
+ specific_value = df_specific[col].values[0]
124
+
125
+ # Highlight specific company's value
126
+ fig.add_trace(go.Scatter(
127
+ y=[specific_value],
128
+ x=[f'母群體-{col}'],
129
+ mode='markers',
130
+ name=f'{company_name}-{col}',
131
+ marker=dict(color='red', size=11, symbol='star'),
132
+ showlegend=True,
133
+ hovertext=f'公司名稱: {company_name}, 值: {specific_value}'
134
+ ))
135
+
136
+ # Update layout
137
+ fig.update_layout(
138
+ title=f"廢棄物統計數據箱型圖 (包含指定公司名稱 {company_name} 數據)",
139
+ yaxis_title="數值 (公噸)",
140
+ xaxis_title="廢棄物項目",
141
+ boxmode='group'
142
+ )
143
+
144
+ # Display the plot in Streamlit
145
+ st.plotly_chart(fig)
146
+
147
+
148
+ # Main function update
149
+ def main():
150
+ st.title("公司數據分析儀表板")
151
+
152
+ # File upload
153
+ st.sidebar.header("上傳 CSV 檔案")
154
+ investor_file = st.sidebar.file_uploader("上傳 投資人溝通.csv", type=["csv"])
155
+ board_file = st.sidebar.file_uploader("上傳 董事會.csv", type=["csv"])
156
+ emission_file = st.sidebar.file_uploader("上傳 溫室氣體排放.csv", type=["csv"])
157
+ energy_file = st.sidebar.file_uploader("上傳 能源管理.csv", type=["csv"])
158
+ waste_file = st.sidebar.file_uploader("上傳 廢棄物管理.csv", type=["csv"])
159
+
160
+ # Load data
161
+ investor_df = load_data(investor_file)
162
+ board_df = load_data(board_file)
163
+ emission_df = load_data(emission_file)
164
+ energy_df = load_data(energy_file)
165
+ waste_df = load_data(waste_file)
166
+
167
+ # Merge data
168
+ merged_df1 = merge_dataframes(investor_df, board_df, ["公司代號", "公司名稱", "出表日期", "報告年度"])
169
+ merged_df2 = merge_dataframes(emission_df, energy_df, ["公司代號", "公司名稱", "出表日期", "報告年度"])
170
+
171
+ # User input
172
+ prefix = st.sidebar.text_input("輸入公司代號前兩位")
173
+ specific_company_code = st.sidebar.text_input("輸入四位數字公司代號")
174
+
175
+ # Waste management analysis
176
+ if waste_df is not None and prefix:
177
+ waste_df['公司代號前兩位'] = waste_df['公司代號'].astype(str).str[:2]
178
+ df_group = waste_df[waste_df['公司代號前兩位'] == prefix]
179
+ df_specific = waste_df[waste_df['公司代號'] == specific_company_code]
180
+
181
+ if not df_specific.empty:
182
+ company_name = df_specific['公司名稱'].values[0]
183
+ plot_waste_management(df_group, df_specific, company_name)
184
+ else:
185
+ st.warning(f"找不到公司代號為 {specific_company_code} 的廢棄物管理數據")
186
+
187
+
188
+
189
+ # Handle 投資人溝通和董事會資料
190
+ if merged_df1 is not None and prefix and specific_company_code:
191
+ columns_of_interest = ['董事出席董事會出席率', '董事進修時數符合進修要點比率', '公司年度召開法說會次數(次)']
192
+ for col in ['董事出席董事會出席率', '董事進修時數符合進修要點比率']:
193
+ merged_df1[col] = merged_df1[col].replace({'%': ''}, regex=True).astype(float)
194
+
195
+ filtered_df1 = filter_dataframe(merged_df1, prefix)
196
+ avg_values = filtered_df1[columns_of_interest].mean()
197
+ specific_company_df1 = get_specific_company(merged_df1, specific_company_code)
198
+
199
+ if not specific_company_df1.empty:
200
+ specific_company_name = specific_company_df1['公司名稱'].iloc[0]
201
+ specific_company_values = specific_company_df1[columns_of_interest].iloc[0]
202
+ plot_radar_chart(avg_values, specific_company_values, ['董事出席率', '董事進修時數符合比率', '年度法說會次數'], prefix, specific_company_name)
203
+ else:
204
+ st.warning(f"找不到公司代號 {specific_company_code} 的資料")
205
+
206
+ # Handle 溫室氣體排放和能源管理資料
207
+ if merged_df2 is not None and prefix:
208
+ emission_columns = ['範疇一排放量(噸CO2e)', '範疇二排放量(噸CO2e)', '範疇三排放量(噸CO2e)']
209
+ energy_column = '使用率(再生能源/總能源)'
210
+ merged_df2[energy_column] = merged_df2[energy_column].replace({'%': ''}, regex=True).astype(float)
211
+
212
+ filtered_df2 = filter_dataframe(merged_df2, prefix)
213
+ specific_company_df2 = get_specific_company(merged_df2, specific_company_code)
214
+
215
+ if not filtered_df2.empty:
216
+ avg_emissions = filtered_df2[emission_columns].mean()
217
+ plot_emission_chart(filtered_df2, avg_emissions, prefix)
218
+
219
+ avg_energy_usage = filtered_df2[energy_column].mean()
220
+ plot_energy_usage(filtered_df2, avg_energy_usage)
221
+
222
+ if not specific_company_df2.empty:
223
+ specific_energy_usage = specific_company_df2[energy_column].iloc[0]
224
+ comparison_data = {
225
+ '公司名稱': [specific_company_df2['公司名稱'].iloc[0], f"{prefix} 母群體平均"],
226
+ '再生能源使用率 (%)': [specific_energy_usage, avg_energy_usage]
227
+ }
228
+ comparison_df = pd.DataFrame(comparison_data)
229
+ st.write("\n再生能源使用率比較表格:")
230
+ st.write(comparison_df)
231
+ else:
232
+ st.warning(f"找不到公司代號 {specific_company_code} 的能源管理數據")
233
+ else:
234
+ st.warning(f"找不到前兩碼為 {prefix} 的公司數據")
235
+
236
+ if __name__ == "__main__":
237
+ main()