# 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()