ESG_Dashboard / app.py
Manasa1's picture
Update app.py
f59d75e verified
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)