alexoh2020 commited on
Commit
7e4f1e1
ยท
2 Parent(s): 0f2373c 03c7508

merged w kemming's edits

Browse files
Files changed (2) hide show
  1. README.md +5 -5
  2. src/streamlit_app.py +67 -29
README.md CHANGED
@@ -107,7 +107,7 @@ flowchart TB
107
  end
108
 
109
  subgraph Processing["๐Ÿง  Data Processing"]
110
- F["TextBlob<br/>Sentiment Engine"]
111
  G["Plotly<br/>Visualizations"]
112
  H["Pandas<br/>Data Processing"]
113
  end
@@ -127,10 +127,10 @@ flowchart TB
127
  C --> I
128
  C --> J
129
 
130
- classDef frontend fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
131
- classDef application fill:#fff3e0,stroke:#f57c00,stroke-width:2px
132
- classDef processing fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
133
- classDef external fill:#fce4ec,stroke:#c2185b,stroke-width:2px
134
 
135
  class A,B frontend
136
  class C,D,E application
 
107
  end
108
 
109
  subgraph Processing["๐Ÿง  Data Processing"]
110
+ F["TextBlob + VADER<br/>Sentiment Engines"]
111
  G["Plotly<br/>Visualizations"]
112
  H["Pandas<br/>Data Processing"]
113
  end
 
127
  C --> I
128
  C --> J
129
 
130
+ classDef frontend fill:#1f6feb,stroke:#58a6ff,stroke-width:2px,color:#f0f6fc
131
+ classDef application fill:#2ea043,stroke:#3fb950,stroke-width:2px,color:#f0f6fc
132
+ classDef processing fill:#a371f7,stroke:#d2a8ff,stroke-width:2px,color:#f0f6fc
133
+ classDef external fill:#f85149,stroke:#ff7b72,stroke-width:2px,color:#f0f6fc
134
 
135
  class A,B frontend
136
  class C,D,E application
src/streamlit_app.py CHANGED
@@ -8,6 +8,8 @@ import pandas as pd
8
  import plotly.express as px
9
  import json
10
  from api_handler import AINewsAnalyzer
 
 
11
 
12
  # Page configuration
13
  st.set_page_config(
@@ -205,53 +207,85 @@ def main():
205
  st.session_state.df = df
206
  st.session_state.query = final_query
207
  st.session_state.days = days
208
-
209
- # Display results if data is available
210
- if 'df' in st.session_state:
211
  df = st.session_state.df
212
-
213
- # Summary metrics
214
  st.markdown("### ๐Ÿ“Š Analysis Summary")
215
  col1, col2, col3, col4 = st.columns(4)
216
-
217
  with col1:
218
  st.metric("๐Ÿ“ฐ Total Articles", len(df))
219
-
220
  with col2:
221
  avg_polarity = df['sentiment_polarity'].mean()
222
  delta_polarity = f"{avg_polarity:+.3f}"
223
  st.metric("๐ŸŽญ Avg Sentiment", f"{avg_polarity:.3f}", delta_polarity)
224
-
225
  with col3:
226
  positive_pct = (len(df[df['sentiment_label'] == 'positive']) / len(df) * 100)
227
  st.metric("๐Ÿ˜Š Positive %", f"{positive_pct:.1f}%")
228
-
229
  with col4:
230
  unique_sources = df['source'].nunique()
231
  st.metric("๐Ÿ“บ News Sources", unique_sources)
232
-
233
- # Charts
 
234
  st.markdown("### ๐Ÿ“ˆ Visual Analysis")
235
-
236
- # Row 1: Distribution and source analysis
237
  col1, col2 = st.columns(2)
238
-
239
- with col1:
240
- dist_fig = create_sentiment_distribution(df)
241
- if dist_fig:
242
- st.plotly_chart(dist_fig, use_container_width=True)
243
-
244
- with col2:
245
- source_fig = create_source_analysis(df)
246
- if source_fig:
247
- st.plotly_chart(source_fig, use_container_width=True)
248
-
249
- # Row 2: Polarity distribution (full width)
250
- thresh = 0.05 if model_query == "Vader" else 0.1
251
- polarity_fig = create_polarity_distribution(df, thresh=thresh)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  if polarity_fig:
253
- st.plotly_chart(polarity_fig, use_container_width=True)
254
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
 
256
  else:
257
  # Welcome message
@@ -272,6 +306,10 @@ def main():
272
  - **Interactive Charts** showing trends over time
273
  - **Source Breakdown** to see which outlets cover your topic
274
  """)
 
 
 
 
275
 
276
  if __name__ == "__main__":
277
  main()
 
8
  import plotly.express as px
9
  import json
10
  from api_handler import AINewsAnalyzer
11
+ import io
12
+
13
 
14
  # Page configuration
15
  st.set_page_config(
 
207
  st.session_state.df = df
208
  st.session_state.query = final_query
209
  st.session_state.days = days
210
+
211
+ # ===== Display results if data is available =====
212
+ if 'df' in st.session_state and not st.session_state.df.empty:
213
  df = st.session_state.df
214
+
215
+ # ===== Summary Metrics =====
216
  st.markdown("### ๐Ÿ“Š Analysis Summary")
217
  col1, col2, col3, col4 = st.columns(4)
218
+
219
  with col1:
220
  st.metric("๐Ÿ“ฐ Total Articles", len(df))
 
221
  with col2:
222
  avg_polarity = df['sentiment_polarity'].mean()
223
  delta_polarity = f"{avg_polarity:+.3f}"
224
  st.metric("๐ŸŽญ Avg Sentiment", f"{avg_polarity:.3f}", delta_polarity)
 
225
  with col3:
226
  positive_pct = (len(df[df['sentiment_label'] == 'positive']) / len(df) * 100)
227
  st.metric("๐Ÿ˜Š Positive %", f"{positive_pct:.1f}%")
 
228
  with col4:
229
  unique_sources = df['source'].nunique()
230
  st.metric("๐Ÿ“บ News Sources", unique_sources)
231
+
232
+
233
+ # ===== Charts =====
234
  st.markdown("### ๐Ÿ“ˆ Visual Analysis")
 
 
235
  col1, col2 = st.columns(2)
236
+
237
+ # Sentiment Distribution
238
+ dist_fig = create_sentiment_distribution(df)
239
+ if dist_fig:
240
+ st.plotly_chart(dist_fig, use_container_width=True, key="dist_fig")
241
+ # Export buttons
242
+ buf = io.BytesIO()
243
+ dist_fig.update_layout(template="plotly_white")
244
+ dist_fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') # ่ฎพ็ฝฎ็™ฝๅบ•
245
+ dist_fig.write_image(buf, format="png", engine="kaleido")
246
+ st.download_button("๐Ÿ“ท Download Distribution Chart as PNG", buf.getvalue(),
247
+ "distribution_chart.png", mime="image/png")
248
+ st.download_button("๐ŸŒ Download Distribution Chart as HTML",
249
+ dist_fig.to_html().encode("utf-8"), "distribution_chart.html",
250
+ mime="text/html")
251
+
252
+ # Source Analysis
253
+ source_fig = create_source_analysis(df)
254
+ if source_fig:
255
+ st.plotly_chart(source_fig, use_container_width=True, key="source_fig")
256
+ buf = io.BytesIO()
257
+ source_fig.update_layout(template="plotly_white")
258
+ source_fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') # ็™ฝๅบ•
259
+ source_fig.write_image(buf, format="png", engine="kaleido")
260
+ st.download_button("๐Ÿ“ท Download Source Chart as PNG", buf.getvalue(),
261
+ "source_chart.png", mime="image/png")
262
+ st.download_button("๐ŸŒ Download Source Chart as HTML",
263
+ source_fig.to_html().encode("utf-8"), "source_chart.html",
264
+ mime="text/html")
265
+
266
+ # Polarity Distribution
267
+ polarity_fig = create_polarity_distribution(df)
268
  if polarity_fig:
269
+ st.plotly_chart(polarity_fig, use_container_width=True, key="polarity_fig")
270
+ buf = io.BytesIO()
271
+ polarity_fig.update_layout(template="plotly_white")
272
+ polarity_fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') # ็™ฝๅบ•
273
+ polarity_fig.write_image(buf, format="png", engine="kaleido")
274
+ st.download_button("๐Ÿ“ท Download Polarity Chart as PNG", buf.getvalue(),
275
+ "polarity_chart.png", mime="image/png")
276
+ st.download_button("๐ŸŒ Download Polarity Chart as HTML",
277
+ polarity_fig.to_html().encode("utf-8"), "polarity_chart.html",
278
+ mime="text/html")
279
+
280
+
281
+ # ===== Export CSV button =====
282
+ csv_data = df.to_csv(index=False).encode('utf-8')
283
+ st.download_button(
284
+ label="๐Ÿ’พ Export Analysis as CSV",
285
+ data=csv_data,
286
+ file_name=f"ai_news_analysis_{st.session_state.query.replace(' ', '_')}.csv",
287
+ mime='text/csv'
288
+ )
289
 
290
  else:
291
  # Welcome message
 
306
  - **Interactive Charts** showing trends over time
307
  - **Source Breakdown** to see which outlets cover your topic
308
  """)
309
+ pass
310
+
311
+
312
+
313
 
314
  if __name__ == "__main__":
315
  main()