File size: 4,886 Bytes
d137217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import os
import requests
import pandas as pd
import plotly.express as px
import gradio as gr
from sklearn.preprocessing import StandardScaler

# Fetch the FRED API key from environment variables
API_KEY = os.getenv("FRED_API_KEY")

def fetch_data(series_id, frequency="m", adjustment="sa"):
    """
    Fetch data from FRED API based on the provided series ID, frequency, and adjustment type.
    """
    if not API_KEY:
        raise ValueError("FRED API key not set. Please set the FRED_API_KEY environment variable.")
    
    url = "https://api.stlouisfed.org/fred/series/observations"
    params = {
        'api_key': API_KEY,
        'series_id': series_id,
        'file_type': 'json',
        'frequency': frequency,
        'seasonal_adjustment': adjustment,
    }
    try:
        response = requests.get(url, params=params)
        response.raise_for_status()
        data = response.json()
        return data
    except requests.exceptions.RequestException as e:
        print(f"Error fetching data for {series_id}: {e}")
        return {}

def process_data(data):
    """
    Process the FRED data into a pandas DataFrame.
    """
    if 'observations' not in data:
        print("No observations found in data.")
        return pd.DataFrame()
    
    df = pd.DataFrame(data['observations'])
    df['date'] = pd.to_datetime(df['date'])
    df['value'] = pd.to_numeric(df['value'], errors='coerce')
    return df

def standardize_series(df):
    """
    Standardize the 'value' column in the dataframe using Z-scores.
    """
    scaler = StandardScaler()
    df['standardized_value'] = scaler.fit_transform(df[['value']])
    return df

def create_combined_2d_visualization(dataframes, labels):
    """
    Generate a combined 2D line plot using Plotly.
    Each dataframe will be plotted on the same axes.
    """
    combined_df = pd.concat(dataframes, keys=labels, names=['series', 'index']).reset_index(level='series')
    fig = px.line(
        combined_df,
        x='date',
        y='standardized_value',
        color='series',
        title="Combined Economic Data 2D Visualization",
        labels={"standardized_value": "Standardized Value", "date": "Date", "series": "Data Type"}
    )
    fig.update_layout(
        width=1200,
        height=600,
        xaxis_title="Date",
        yaxis_title="Standardized Value",
        legend_title="Data Type"
    )
    return fig

def visualize_multiple_series(series_names):
    """
    Fetch, standardize, and combine multiple datasets for visualization.
    """
    dataframes = []
    labels = []
    for series_name in series_names:
        series_id = series_options.get(series_name)
        frequency = default_frequencies.get(series_id, "m")
        adjustment = default_adjustments.get(series_id, "sa")
        data = fetch_data(series_id, frequency, adjustment)
        df = process_data(data)
        if not df.empty:
            standardized_df = standardize_series(df)
            dataframes.append(standardized_df)
            labels.append(series_name)
    
    if not dataframes:
        raise ValueError("No valid data to visualize.")
    return create_combined_2d_visualization(dataframes, labels)

# Define default frequencies and adjustments
default_frequencies = {
    "GDP": "q",
    "UNRATE": "m",
    "CPIAUCSL": "m",
    "FEDFUNDS": "m",
    "MORTGAGE30US": "w"
}

default_adjustments = {
    "GDP": "sa",
    "UNRATE": "sa",
    "CPIAUCSL": "sa",
    "FEDFUNDS": "nsa",
    "MORTGAGE30US": "nsa"
}

# Define options for each dropdown
series_options = {
    "Gross Domestic Product (GDP)": "GDP",
    "Unemployment Rate (UNRATE)": "UNRATE",
    "Consumer Price Index (CPI - All Urban Consumers)": "CPIAUCSL",
    "Federal Funds Rate": "FEDFUNDS",
    "30-Year Fixed Mortgage Rate": "MORTGAGE30US"
}

# Gradio Interface using Blocks
with gr.Blocks() as demo:
    gr.Markdown("# FRED Combined Data 2D Visualizer")
    gr.Markdown("Choose multiple economic indicators to visualize them together in a 2D space.")
    
    with gr.Row():
        series_dropdown = gr.CheckboxGroup(
            choices=list(series_options.keys()),
            label="Select Economic Indicators to Compare"
        )
    
    plot_output = gr.Plot()

    # Explanation Section
    with gr.Accordion("Color Coding Explanation", open=True):
        gr.Markdown("""
        - **Gross Domestic Product (GDP)**: Displayed in **blue**.
        - **Unemployment Rate (UNRATE)**: Displayed in **green**.
        - **Consumer Price Index (CPI - All Urban Consumers)**: Displayed in **red**.
        - **Federal Funds Rate**: Displayed in **purple**.
        - **30-Year Fixed Mortgage Rate**: Displayed in **orange**.
        """)
    
    # Define interaction
    series_dropdown.change(
        visualize_multiple_series, 
        inputs=[series_dropdown], 
        outputs=[plot_output]
    )

demo.launch(debug=True)