I need an app that let's me view results and add forecast trendlines based on input from a user using a datagrid
Drop files here
or click to upload
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from st_aggrid import AgGrid, GridOptionsBuilder
from datetime import datetime, timedelta
st.title("Forecast Trend Analyzer")
# Create sample data if none exists in session state
if 'data' not in st.session_state:
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='M')
values = np.random.normal(100, 10, len(dates))
st.session_state.data = pd.DataFrame({
'Date': dates,
'Value': values
})
# Grid options
gb = GridOptionsBuilder.from_dataframe(st.session_state.data)
gb.configure_default_column(editable=True)
gb.configure_column('Date', editable=False)
grid_options = gb.build()
# Sidebar controls
st.sidebar.header("Forecast Settings")
forecast_periods = st.sidebar.slider("Forecast Periods (Months)", 1, 12, 6)
confidence_interval = st.sidebar.slider("Confidence Interval (%)", 70, 95, 85)
# Display grid
st.subheader("Historical Data")
grid_response = AgGrid(
st.session_state.data,
gridOptions=grid_options,
height=300,
fit_columns_on_grid_load=True
)
# Get updated data from grid
df = grid_response['data']
# Calculate forecast
def calculate_forecast(data, periods, confidence):
X = np.arange(len(data))
y = data['Value'].values
# Fit linear regression
coefficients = np.polyfit(X, y, 1)
trend = np.poly1d(coefficients)
# Generate forecast
forecast_X = np.arange(len(data), len(data) + periods)
forecast_y = trend(forecast_X)
# Calculate confidence intervals
std_dev = np.std(y - trend(X))
z_score = {70: 1.04, 75: 1.15, 80: 1.28, 85: 1.44, 90: 1.645, 95: 1.96}
margin = z_score[confidence] * std_dev
return forecast_y, margin
# Generate forecast
forecast_y, margin = calculate_forecast(df, forecast_periods, confidence_interval)
# Create forecast dates
last_date = pd.to_datetime(df['Date'].iloc[-1])
forecast_dates = pd.date_range(start=last_date + timedelta(days=31),
periods=forecast_periods,
freq='M')
# Create plot
fig = go.Figure()
# Add historical data
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['Value'],
name='Historical Data',
mode='lines+markers'
))
# Add forecast
fig.add_trace(go.Scatter(
x=forecast_dates,
y=forecast_y,
name='Forecast',
mode='lines',
line=dict(dash='dash')
))
# Add confidence intervals
fig.add_trace(go.Scatter(
x=forecast_dates,
y=forecast_y + margin,
fill=None,
mode='lines',
line=dict(width=0),
showlegend=False
))
fig.add_trace(go.Scatter(
x=forecast_dates,
y=forecast_y - margin,
fill='tonexty',
mode='lines',
line=dict(width=0),
name=f'{confidence_interval}% Confidence Interval'
))
# Update layout
fig.update_layout(
title='Historical Data and Forecast',
xaxis_title='Date',
yaxis_title='Value',
hovermode='x unified'
)
# Display plot
st.plotly_chart(fig, use_container_width=True)
# Display forecast summary
st.subheader("Forecast Summary")
forecast_df = pd.DataFrame({
'Date': forecast_dates,
'Forecast': forecast_y,
'Lower Bound': forecast_y - margin,
'Upper Bound': forecast_y + margin
}).round(2)
st.dataframe(forecast_df)
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?