Keming commited on
Commit
29055b4
ยท
1 Parent(s): 097fe34

Add PNG/HTML export for charts and CSV export for analysis

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +103 -64
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(
@@ -200,72 +202,109 @@ def main():
200
  st.session_state.df = df
201
  st.session_state.query = final_query
202
  st.session_state.days = days
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
- # Display results if data is available
205
- if 'df' in st.session_state:
206
- df = st.session_state.df
207
-
208
- # Summary metrics
209
- st.markdown("### ๐Ÿ“Š Analysis Summary")
210
- col1, col2, col3, col4 = st.columns(4)
211
-
212
- with col1:
213
- st.metric("๐Ÿ“ฐ Total Articles", len(df))
214
-
215
- with col2:
216
- avg_polarity = df['sentiment_polarity'].mean()
217
- delta_polarity = f"{avg_polarity:+.3f}"
218
- st.metric("๐ŸŽญ Avg Sentiment", f"{avg_polarity:.3f}", delta_polarity)
219
-
220
- with col3:
221
- positive_pct = (len(df[df['sentiment_label'] == 'positive']) / len(df) * 100)
222
- st.metric("๐Ÿ˜Š Positive %", f"{positive_pct:.1f}%")
223
-
224
- with col4:
225
- unique_sources = df['source'].nunique()
226
- st.metric("๐Ÿ“บ News Sources", unique_sources)
227
-
228
- # Charts
229
- st.markdown("### ๐Ÿ“ˆ Visual Analysis")
230
-
231
- # Row 1: Distribution and source analysis
232
- col1, col2 = st.columns(2)
233
-
234
- with col1:
235
- dist_fig = create_sentiment_distribution(df)
236
- if dist_fig:
237
- st.plotly_chart(dist_fig, use_container_width=True)
238
-
239
- with col2:
240
- source_fig = create_source_analysis(df)
241
- if source_fig:
242
- st.plotly_chart(source_fig, use_container_width=True)
243
-
244
- # Row 2: Polarity distribution (full width)
245
- polarity_fig = create_polarity_distribution(df)
246
- if polarity_fig:
247
- st.plotly_chart(polarity_fig, use_container_width=True)
248
-
249
 
250
- else:
251
- # Welcome message
252
- st.info("๐Ÿ‘‹ Welcome! Configure your analysis settings in the sidebar and click 'Analyze News' to get started.")
253
-
254
- # Sample visualization or instructions
255
- st.markdown("""
256
- ### ๐Ÿš€ How to Use:
257
-
258
- 1. **Choose a topic** from the dropdown or enter your own search term
259
- 2. **Select time range** (1-30 days) to analyze recent news
260
- 3. **Pick news sources** or leave as 'All Sources' for comprehensive coverage
261
- 4. **Click 'Analyze News'** to fetch and analyze articles
262
-
263
- ### ๐Ÿ“Š What You'll Get:
264
-
265
- - **Sentiment Analysis** of headlines and descriptions
266
- - **Interactive Charts** showing trends over time
267
- - **Source Breakdown** to see which outlets cover your topic
268
- """)
269
 
270
  if __name__ == "__main__":
271
  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(
 
202
  st.session_state.df = df
203
  st.session_state.query = final_query
204
  st.session_state.days = days
205
+
206
+ # ===== Display results if data is available =====
207
+ if 'df' in st.session_state and not st.session_state.df.empty:
208
+ df = st.session_state.df
209
+
210
+ # ===== Summary Metrics =====
211
+ st.markdown("### ๐Ÿ“Š Analysis Summary")
212
+ col1, col2, col3, col4 = st.columns(4)
213
+
214
+ with col1:
215
+ st.metric("๐Ÿ“ฐ Total Articles", len(df))
216
+ with col2:
217
+ avg_polarity = df['sentiment_polarity'].mean()
218
+ delta_polarity = f"{avg_polarity:+.3f}"
219
+ st.metric("๐ŸŽญ Avg Sentiment", f"{avg_polarity:.3f}", delta_polarity)
220
+ with col3:
221
+ positive_pct = (len(df[df['sentiment_label'] == 'positive']) / len(df) * 100)
222
+ st.metric("๐Ÿ˜Š Positive %", f"{positive_pct:.1f}%")
223
+ with col4:
224
+ unique_sources = df['source'].nunique()
225
+ st.metric("๐Ÿ“บ News Sources", unique_sources)
226
+
227
+
228
+ # ===== Charts =====
229
+ st.markdown("### ๐Ÿ“ˆ Visual Analysis")
230
+ col1, col2 = st.columns(2)
231
+
232
+ # Sentiment Distribution
233
+ dist_fig = create_sentiment_distribution(df)
234
+ if dist_fig:
235
+ st.plotly_chart(dist_fig, use_container_width=True, key="dist_fig")
236
+ # Export buttons
237
+ buf = io.BytesIO()
238
+ dist_fig.update_layout(template="plotly_white")
239
+ dist_fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') # ่ฎพ็ฝฎ็™ฝๅบ•
240
+ dist_fig.write_image(buf, format="png", engine="kaleido")
241
+ st.download_button("๐Ÿ“ท Download Distribution Chart as PNG", buf.getvalue(),
242
+ "distribution_chart.png", mime="image/png")
243
+ st.download_button("๐ŸŒ Download Distribution Chart as HTML",
244
+ dist_fig.to_html().encode("utf-8"), "distribution_chart.html",
245
+ mime="text/html")
246
+
247
+ # Source Analysis
248
+ source_fig = create_source_analysis(df)
249
+ if source_fig:
250
+ st.plotly_chart(source_fig, use_container_width=True, key="source_fig")
251
+ buf = io.BytesIO()
252
+ source_fig.update_layout(template="plotly_white")
253
+ source_fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') # ็™ฝๅบ•
254
+ source_fig.write_image(buf, format="png", engine="kaleido")
255
+ st.download_button("๐Ÿ“ท Download Source Chart as PNG", buf.getvalue(),
256
+ "source_chart.png", mime="image/png")
257
+ st.download_button("๐ŸŒ Download Source Chart as HTML",
258
+ source_fig.to_html().encode("utf-8"), "source_chart.html",
259
+ mime="text/html")
260
+
261
+ # Polarity Distribution
262
+ polarity_fig = create_polarity_distribution(df)
263
+ if polarity_fig:
264
+ st.plotly_chart(polarity_fig, use_container_width=True, key="polarity_fig")
265
+ buf = io.BytesIO()
266
+ polarity_fig.update_layout(template="plotly_white")
267
+ polarity_fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') # ็™ฝๅบ•
268
+ polarity_fig.write_image(buf, format="png", engine="kaleido")
269
+ st.download_button("๐Ÿ“ท Download Polarity Chart as PNG", buf.getvalue(),
270
+ "polarity_chart.png", mime="image/png")
271
+ st.download_button("๐ŸŒ Download Polarity Chart as HTML",
272
+ polarity_fig.to_html().encode("utf-8"), "polarity_chart.html",
273
+ mime="text/html")
274
+
275
+
276
+ # ===== Export CSV button =====
277
+ csv_data = df.to_csv(index=False).encode('utf-8')
278
+ st.download_button(
279
+ label="๐Ÿ’พ Export Analysis as CSV",
280
+ data=csv_data,
281
+ file_name=f"ai_news_analysis_{st.session_state.query.replace(' ', '_')}.csv",
282
+ mime='text/csv'
283
+ )
284
+
285
 
286
+ else:
287
+ # Welcome message
288
+ st.info("๐Ÿ‘‹ Welcome! Configure your analysis settings in the sidebar and click 'Analyze News' to get started.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
 
290
+ # Sample visualization or instructions
291
+ st.markdown("""
292
+ ### ๐Ÿš€ How to Use:
293
+
294
+ 1. **Choose a topic** from the dropdown or enter your own search term
295
+ 2. **Select time range** (1-30 days) to analyze recent news
296
+ 3. **Pick news sources** or leave as 'All Sources' for comprehensive coverage
297
+ 4. **Click 'Analyze News'** to fetch and analyze articles
298
+
299
+ ### ๐Ÿ“Š What You'll Get:
300
+
301
+ - **Sentiment Analysis** of headlines and descriptions
302
+ - **Interactive Charts** showing trends over time
303
+ - **Source Breakdown** to see which outlets cover your topic
304
+ """)
305
+
306
+
307
+
 
308
 
309
  if __name__ == "__main__":
310
  main()