Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import yfinance as yf | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| from typing import Tuple, Optional | |
| import logging | |
| # Set up logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| # Mapping company names to their ticker symbols | |
| COMPANY_DICT = { | |
| "Apple": "AAPL", | |
| "Google": "GOOGL", | |
| "Microsoft": "MSFT", | |
| "Amazon": "AMZN", | |
| "Tesla": "TSLA", | |
| "Meta": "META", | |
| "NVIDIA": "NVDA", | |
| "Netflix": "NFLX" | |
| } | |
| def create_line_plot(df: pd.DataFrame, company_name: str) -> go.Figure: | |
| """Create a line plot using plotly""" | |
| fig = go.Figure() | |
| fig.add_trace(go.Scatter( | |
| x=df["ESG Category"], | |
| y=df["Score"], | |
| mode='lines+markers', | |
| name='ESG Score', | |
| line=dict(color='rgb(55, 83, 109)', width=2), | |
| marker=dict(size=10) | |
| )) | |
| fig.update_layout( | |
| title=f"ESG Scores Trend for {company_name}", | |
| xaxis_title="ESG Category", | |
| yaxis_title="Score", | |
| yaxis_range=[0, 100], | |
| height=400, | |
| template='plotly_white' | |
| ) | |
| return fig | |
| def create_scatter_plot(df: pd.DataFrame, company_name: str) -> go.Figure: | |
| """Create a scatter plot using plotly""" | |
| fig = go.Figure() | |
| fig.add_trace(go.Scatter( | |
| x=df["ESG Category"], | |
| y=df["Score"], | |
| mode='markers', | |
| marker=dict( | |
| size=15, | |
| color='rgb(55, 83, 109)', | |
| line=dict( | |
| color='rgb(8,48,107)', | |
| width=2 | |
| ) | |
| ), | |
| name='ESG Score' | |
| )) | |
| fig.update_layout( | |
| title=f"ESG Score Distribution for {company_name}", | |
| xaxis_title="ESG Category", | |
| yaxis_title="Score", | |
| yaxis_range=[0, 100], | |
| height=400, | |
| template='plotly_white' | |
| ) | |
| return fig | |
| def create_bar_plot(df: pd.DataFrame, company_name: str) -> go.Figure: | |
| """Create a bar plot using plotly""" | |
| fig = go.Figure() | |
| fig.add_trace(go.Bar( | |
| x=df["ESG Category"], | |
| y=df["Score"], | |
| marker_color='rgb(55, 83, 109)', | |
| name='ESG Score' | |
| )) | |
| fig.update_layout( | |
| title=f"ESG Scores Comparison for {company_name}", | |
| xaxis_title="ESG Category", | |
| yaxis_title="Score", | |
| yaxis_range=[0, 100], | |
| height=400, | |
| template='plotly_white' | |
| ) | |
| return fig | |
| def create_pie_chart(df: pd.DataFrame, company_name: str) -> go.Figure: | |
| """Create a pie chart using plotly""" | |
| total_score = df['Score'].sum() | |
| percentages = (df['Score'] / total_score * 100).round(1) | |
| # Create labels with both category and percentage | |
| labels = [f"{cat} ({pct}%)" for cat, pct in zip(df['ESG Category'], percentages)] | |
| fig = go.Figure() | |
| fig.add_trace(go.Pie( | |
| labels=labels, | |
| values=df['Score'], | |
| hole=0.4, # Creates a donut chart | |
| marker=dict( | |
| colors=['rgb(55, 83, 109)', 'rgb(26, 118, 255)', 'rgb(178, 200, 223)'] | |
| ), | |
| textinfo='label+value', | |
| textposition='outside', | |
| texttemplate='%{label}<br>Score: %{value:.1f}' | |
| )) | |
| fig.update_layout( | |
| title=f"ESG Score Distribution for {company_name}", | |
| height=400, | |
| template='plotly_white', | |
| showlegend=False | |
| ) | |
| return fig | |
| def create_empty_plot(message: str) -> go.Figure: | |
| """Create an empty plot with an error message""" | |
| fig = go.Figure() | |
| fig.add_annotation( | |
| text=message, | |
| xref="paper", | |
| yref="paper", | |
| x=0.5, | |
| y=0.5, | |
| showarrow=False, | |
| font=dict(size=14) | |
| ) | |
| fig.update_layout( | |
| xaxis_visible=False, | |
| yaxis_visible=False, | |
| height=400 | |
| ) | |
| return fig | |
| def fetch_esg_data(company_name: str) -> Tuple[Optional[pd.DataFrame], str]: | |
| """ | |
| Fetch and process ESG data for the selected company. | |
| """ | |
| try: | |
| ticker = COMPANY_DICT[company_name] | |
| logger.info(f"Fetching ESG data for {company_name} ({ticker})") | |
| stock = yf.Ticker(ticker) | |
| esg_data = stock.sustainability | |
| if esg_data is None: | |
| return None, f"No ESG data available for {company_name}" | |
| esg_df = pd.DataFrame(esg_data) | |
| esg_scores = esg_df.loc[["environmentScore", "socialScore", "governanceScore"], :].dropna().astype(float) | |
| plot_df = pd.DataFrame({ | |
| "ESG Category": ["Environment", "Social", "Governance"], | |
| "Score": esg_scores.squeeze().values | |
| }) | |
| return plot_df, f"Successfully fetched ESG data for {company_name}" | |
| except Exception as e: | |
| logger.error(f"Error fetching ESG data: {str(e)}") | |
| return None, f"Error fetching ESG data: {str(e)}" | |
| def create_interface() -> gr.Blocks: | |
| """Create the Gradio interface""" | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| gr.Markdown("# ESG Data Visualization Dashboard") | |
| gr.Markdown("Analyze Environmental, Social, and Governance scores for major tech companies.") | |
| with gr.Tab("ESG Analysis"): | |
| with gr.Row(): | |
| with gr.Column(): | |
| company = gr.Dropdown( | |
| label="Select Company", | |
| choices=list(COMPANY_DICT.keys()), | |
| value="Apple" | |
| ) | |
| plot_button = gr.Button("Generate ESG Analysis", variant="primary") | |
| status_message = gr.Textbox( | |
| label="Status", | |
| interactive=False, | |
| visible=True | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| line_plot = gr.Plot(label="Trend Analysis") | |
| with gr.Column(): | |
| pie_plot = gr.Plot(label="Distribution Analysis") | |
| with gr.Row(): | |
| with gr.Column(): | |
| scatter_plot = gr.Plot(label="Score Distribution") | |
| with gr.Column(): | |
| bar_plot = gr.Plot(label="Score Comparison") | |
| def process_esg_request(company_name: str) -> Tuple[go.Figure, go.Figure, go.Figure, go.Figure, str]: | |
| # Fetch the data | |
| plot_df, status = fetch_esg_data(company_name) | |
| if plot_df is None: | |
| empty_plot = create_empty_plot(status) | |
| return empty_plot, empty_plot, empty_plot, empty_plot, status | |
| # Create all plots | |
| line = create_line_plot(plot_df, company_name) | |
| scatter = create_scatter_plot(plot_df, company_name) | |
| bar = create_bar_plot(plot_df, company_name) | |
| pie = create_pie_chart(plot_df, company_name) | |
| return line, pie, scatter, bar, status | |
| # Connect the button click to the process function | |
| plot_button.click( | |
| fn=process_esg_request, | |
| inputs=company, | |
| outputs=[line_plot, pie_plot, scatter_plot, bar_plot, status_message], | |
| api_name="generate_esg_analysis" | |
| ) | |
| with gr.Tab("About"): | |
| gr.Markdown(""" | |
| ## About This Dashboard | |
| This dashboard provides ESG (Environmental, Social, and Governance) data visualization for major technology companies. The data is sourced from Yahoo Finance and updated regularly. | |
| ### How to Use | |
| 1. Select a company from the dropdown menu | |
| 2. Click 'Generate ESG Analysis' to view multiple visualizations: | |
| - Trend Analysis: Shows the progression across ESG categories | |
| - Distribution Analysis: Shows the relative proportion of each ESG component | |
| - Score Distribution: Displays the spread of ESG scores | |
| - Score Comparison: Compares ESG scores side by side | |
| ### Metrics Explained | |
| - **Environmental Score**: Measures company's environmental impact and sustainability initiatives | |
| - **Social Score**: Evaluates company's relationships with employees, suppliers, customers, and communities | |
| - **Governance Score**: Assesses company's leadership, executive pay, audits, internal controls, and shareholder rights | |
| """) | |
| return app | |
| if __name__ == "__main__": | |
| app = create_interface() | |
| app.launch(share=True, debug=True) |