lab7 / app.py
jeonghin's picture
Update app.py
77e694f verified
# import panel as pn
# import pandas as pd
# import altair as alt
# # we want to use bootstrap/template, tell Panel to load up what we need
# pn.extension(design='bootstrap')
# # we want to use vega, tell Panel to load up what we need
# pn.extension('vega')
# # create a basic template using bootstrap
# template = pn.template.BootstrapTemplate(
# title='SI649 Altair Assignment',
# )
# # the main column will hold our key content
# maincol = pn.Column()
# # add some markdown to the main column
# maincol.append("# Polling Data Interactive Visualization")
# # load up a dataframe and show it in the main column
# df1=pd.read_csv("https://raw.githubusercontent.com/dallascard/SI649_public/main/altair_hw3/approval_polllist.csv")
# df2=pd.read_csv("https://raw.githubusercontent.com/dallascard/SI649_public/main/altair_hw3/approval_topline.csv")
# # fix the time stamps and reorganize the data to combine approve and disapprove into one column
# df2['timestamp']=pd.to_datetime(df2['timestamp'])
# df2=pd.melt(df2, id_vars=['president', 'subgroup', 'timestamp'], value_vars=['approve','disapprove']).rename(columns={'variable':'choice', 'value':'rate'})
# # Selection widgets
# subgroup_select = pn.widgets.Select(name='Select', options=['Adults', 'Voters', 'All polls'])
# date_slider = pn.widgets.DateRangeSlider(name='Date Range Slider', start=df2['timestamp'].min(), end=df2['timestamp'].max())
# moving_avg_slider = pn.widgets.IntSlider(name='Moving Average Window', start=1, end=100, step=1)
# # Bind the widgets to the create_plot function
# @pn.depends(subgroup_select.param.value, date_slider.param.value, moving_avg_slider.param.value)
# def create_plot(subgroup, date_range, moving_av_window):
# data = df2[(df2['subgroup'] == subgroup) & (df2['choice'] == "approve") & (df2['timestamp'].dt.date.between(date_range[0], date_range[1]))]
# min_rate = df2['rate'].min()
# max_rate = df2['rate'].max()
# data = data.sort_values('timestamp')
# data['moving_avg'] = data['rate'].rolling(window=moving_av_window, min_periods=1).mean()
# # Line chart for moving average
# line = alt.Chart(data).mark_line(interpolate='natural').encode(
# x=alt.X('timestamp:T', axis=alt.Axis(title='', format='%b %d, %Y')),
# y=alt.Y('moving_avg:Q', axis=alt.Axis(title='approve,mov_avg'), scale=alt.Scale(domain=[min_rate, max_rate])),
# color=alt.value('red')
# )
# # Scatter plot for individual data points
# points = alt.Chart(data).mark_point().encode(
# x=alt.X('timestamp:T'),
# y=alt.Y('rate:Q', axis=alt.Axis(title='approve,mov_avg'), scale=alt.Scale(domain=[min_rate, max_rate])),
# color=alt.value('gray'),
# tooltip=['timestamp:T', 'rate:Q']
# )
# # Combine line chart and scatter plot
# plot = alt.layer(points, line).resolve_scale(y='shared')
# return plot
# # app = pn.Column("# Polling Data Interactive Visualization", pn.panel(create_plot, reactive=True), subgroup_select, date_slider, moving_avg_slider)
# maincol.append(pn.panel(create_plot, reactive=True))
# maincol.append(subgroup_select)
# maincol.append(date_slider)
# maincol.append(moving_avg_slider)
# # add the main column to the template
# template.main.append(maincol)
# # Indicate that the template object is the "application" and serve it
# template.servable(title="SI649 Altair Assignment")
import panel as pn
import pandas as pd
import altair as alt
# Ensure Panel and Altair extensions are loaded
pn.extension('vega', design='bootstrap')
# Load data
df1 = pd.read_csv("https://raw.githubusercontent.com/dallascard/SI649_public/main/altair_hw3/approval_polllist.csv")
df2 = pd.read_csv("https://raw.githubusercontent.com/dallascard/SI649_public/main/altair_hw3/approval_topline.csv")
# Data preprocessing
df2['timestamp'] = pd.to_datetime(df2['timestamp'])
df2 = pd.melt(df2, id_vars=['president', 'subgroup', 'timestamp'], value_vars=['approve', 'disapprove']).rename(columns={'variable': 'choice', 'value': 'rate'})
# Widgets
subgroup_select = pn.widgets.Select(name='Select Subgroup', options=['Adults', 'Voters', 'All polls'])
date_slider = pn.widgets.DateRangeSlider(name='Date Range Slider', start=df2['timestamp'].min(), end=df2['timestamp'].max())
moving_avg_slider = pn.widgets.IntSlider(name='Moving Average Window', start=1, end=100, step=1)
# Visualization function
@pn.depends(subgroup_select.param.value, date_slider.param.value, moving_avg_slider.param.value)
def create_plot(subgroup, date_range, moving_av_window):
start_date, end_date = date_range[0], date_range[1] # Convert to date
data = df2[(df2['subgroup'] == subgroup) & (df2['choice'] == "approve") & (pd.to_datetime(df2['timestamp']) >= pd.to_datetime(start_date)) & (pd.to_datetime(df2['timestamp']) <= pd.to_datetime(end_date))]
min_rate = df2['rate'].min()
max_rate = df2['rate'].max()
data = data.sort_values('timestamp')
data['moving_avg'] = data['rate'].rolling(window=moving_av_window, min_periods=1).mean()
# Line chart for moving average
line = alt.Chart(data).mark_line(interpolate='natural').encode(
x=alt.X('timestamp:T', axis=alt.Axis(title='', format='%b %d, %Y')),
y=alt.Y('moving_avg:Q', axis=alt.Axis(title='approve,mov_avg'), scale=alt.Scale(domain=[min_rate, max_rate])),
color=alt.value('red')
)
# Scatter plot for individual data points
points = alt.Chart(data).mark_point().encode(
x=alt.X('timestamp:T'),
y=alt.Y('rate:Q', axis=alt.Axis(title='approve,mov_avg'), scale=alt.Scale(domain=[min_rate, max_rate])),
color=alt.value('gray'),
tooltip=['timestamp:T', 'rate:Q']
)
# Combine line chart and scatter plot
plot = alt.layer(points, line).resolve_scale(y='shared')
return plot
# Main layout
main_layout = pn.Column(
"# Polling Data Interactive Visualization",
pn.panel(create_plot, reactive=True),
subgroup_select,
date_slider,
moving_avg_slider,
)
# Create a basic template
template = pn.template.BootstrapTemplate(title='SI649 Altair Assignment')
template.main.append(main_layout)
# Serve the application
template.servable()