Spaces:
Running
Running
import os | |
import requests | |
import pandas as pd | |
import plotly.graph_objects as go | |
import gradio as gr | |
# Set FRED API Key from environment variable | |
FRED_API_KEY = os.getenv('FRED_API_KEY') | |
# List of FRED data series and their descriptive labels | |
series_options = { | |
"UNRATE": "Unemployment Rate", | |
"GDP": "Gross Domestic Product", | |
"CPIAUCSL": "Consumer Price Index for All Urban Consumers", | |
"DGS10": "10-Year Treasury Constant Maturity Rate", | |
"FEDFUNDS": "Effective Federal Funds Rate", | |
"M1SL": "M1 Money Supply", | |
"M2SL": "M2 Money Supply", | |
"M3SL": "M3 Money Supply", | |
"HOUST": "Housing Starts", | |
"PCE": "Personal Consumption Expenditures", | |
"BAA10YM": "Moody's Baa Corporate Bond Yield Spread" | |
} | |
# Function to fetch data from the FRED API | |
def fetch_fred_data(series_ids): | |
""" | |
Fetches data for a list of FRED series IDs. | |
Returns a DataFrame with columns as series and dates as rows. | |
""" | |
data = {} | |
for series_id in series_ids: | |
response = requests.get( | |
f'https://api.stlouisfed.org/fred/series/observations', | |
params={ | |
'series_id': series_id, | |
'api_key': FRED_API_KEY, | |
'file_type': 'json' | |
} | |
) | |
if response.status_code == 200: | |
observations = response.json().get('observations', []) | |
dates = [obs['date'] for obs in observations] | |
# Convert values to float, handling invalid entries | |
values = [ | |
float(obs['value']) if obs['value'].replace('.', '', 1).isdigit() else float('nan') | |
for obs in observations | |
] | |
data[series_id] = pd.Series(values, index=dates) | |
else: | |
print(f"Failed to fetch data for {series_id}") | |
return pd.DataFrame(data) | |
# Function to standardize data (z-scores) | |
def standardize_data(df): | |
""" | |
Standardizes each column in the DataFrame to have a mean of 0 and standard deviation of 1. | |
""" | |
return (df - df.mean()) / df.std() | |
# Function to create a responsive 3D correlation matrix | |
def create_3d_correlation_matrix(df): | |
""" | |
Creates a 3D correlation matrix graph using Plotly. | |
The graph will automatically adjust its size. | |
""" | |
correlation_matrix = df.corr() | |
fig = go.Figure(data=[go.Surface( | |
z=correlation_matrix.values, | |
x=correlation_matrix.columns, | |
y=correlation_matrix.index | |
)]) | |
fig.update_layout( | |
title='3D Correlation Matrix (Standardized)', | |
autosize=True, # Enables auto-resizing | |
scene=dict( | |
xaxis=dict(title='Variables'), | |
yaxis=dict(title='Variables'), | |
zaxis=dict(title='Correlation') | |
), | |
margin=dict(l=0, r=0, t=50, b=50) # Adjust margins for better fit | |
) | |
return fig | |
# Gradio function to handle user interaction | |
def visualize_correlation(selected_series): | |
# Map descriptive labels back to FRED series IDs | |
series_ids = [series for series in series_options if series_options[series] in selected_series] | |
if not series_ids: | |
return None, "Please select at least one indicator." | |
# Fetch and process data | |
df = fetch_fred_data(series_ids) | |
if df.empty: | |
return None, "Failed to fetch data for the selected indicators." | |
standardized_df = standardize_data(df) | |
plot = create_3d_correlation_matrix(standardized_df) | |
return plot, None | |
# Gradio Blocks Interface | |
with gr.Blocks() as demo: | |
gr.Markdown("# 3D Correlation Matrix Visualization with FRED Data") | |
with gr.Row(): | |
with gr.Column(): | |
series_selector = gr.CheckboxGroup( | |
choices=list(series_options.values()), | |
label="Select Economic Indicators", | |
info="Choose one or more indicators to include in the correlation matrix." | |
) | |
submit_button = gr.Button("Generate Matrix") | |
with gr.Column(): | |
plot_output = gr.Plot(label="3D Correlation Matrix") | |
error_message = gr.Markdown("", visible=False) | |
# Event handler for the submit button | |
submit_button.click( | |
fn=visualize_correlation, | |
inputs=[series_selector], | |
outputs=[plot_output, error_message], | |
) | |
# Launch the Gradio app | |
demo.launch(debug=True) |