In this lesson, we do our final project! We will be completing our Christmas Songs Analytics Dashboard using Dash and Plotly. We will use the Billboard Christmas Songs dataset to gain insights into the chart performance of Christmas songs over the years. By the end of this lesson, you'll have a thorough understanding of data preparation, visualization creation, and building interactive dashboards, equipping you with the skills needed to analyze and present complex datasets effectively.
First, let's focus on preparing our data using pandas. We will be working with the Billboard Christmas Songs dataset, aiming to gather insights about the songs that have charted over the years. We'll start by loading the data and preparing it for visualization.
Firstly, let's load the dataframe, convert relevant columns to their necessary types, and derive a summary of the top songs:
Python1import pandas as pd 2 3# Load and prepare data 4df = pd.read_csv('billboard_christmas.csv') 5df['weekid'] = pd.to_datetime(df['weekid']) 6 7# Prepare summary data 8top_songs = df.groupby(['song', 'performer']).agg({ 9 'peak_position': 'min', 10 'weeks_on_chart': 'max', 11 'year': ['min', 'max'] 12}).reset_index() 13 14top_songs.columns = ['Song', 'Performer', 'Peak Position', 'Weeks on Chart', 'First Year', 'Last Year'] 15top_songs.sort_values('Peak Position', inplace=True)
We're interested in each song's peak position, the number of weeks it stayed on the chart, and the range of years it appeared. With our top_songs
dataframe, we've derived clean and meaningful summary data. This gives us a strong foundation upon which to build our visualizations.
Let's break down the four visualizations that will make up our dashboard. Each visualization provides a unique insight into the dataset:
-
Timeline Chart: This line chart will showcase the number of Christmas songs making it to the Billboard chart over the years. It gives us a historical perspective on seasonal song popularity.
-
Top Songs Table: A data table highlighting the top-performing Christmas songs based on their peak positions across several artists. We'll list them in ascending order based on their chart position.
-
Seasonal Performance Chart: This bar chart will focus on analyzing the average chart positions of songs on a monthly basis, revealing seasonal trends in song performance.
-
Artist Comparison Chart: This line chart allows users to select artists and compare their songs' performances over time, shedding light on which artists hold the most Christmas chart clout.
These graphs provide a comprehensive overview of the dataset and help reveal trends and patterns in the musical landscape.
To efficiently present our visual insights, we need a structured layout. We'll utilize both HTML and Dash components to design our dashboard for interactivity and user engagement.
First, we create our app layout using Dash, including headers and the arrangement of our visual components:
Python1from dash import Dash, html, dcc, dash_table 2 3# Initialize app 4app = Dash(__name__) 5 6# Layout 7app.layout = html.Div([ 8 html.Div([ 9 html.H1('🎄 Christmas Billboard Hits Dashboard 🎅', 10 style={'color': COLORS['white'], 'textAlign': 'center'}) 11 ], style={ 12 'backgroundColor': COLORS['red'], 13 'padding': '20px', 14 'borderRadius': '10px', 15 'margin': '10px' 16 }), 17 18 html.Div([ 19 html.Div([ 20 html.Div([ 21 html.H3('Christmas Songs Timeline 📊', style={'color': COLORS['green']}), 22 dcc.Graph(id='timeline-chart') 23 ], style={'backgroundColor': COLORS['white'], 'padding': '20px', 'borderRadius': '10px', 'marginBottom': '20px'}), 24 25 html.Div([ 26 html.H3('Top Christmas Songs 🎵', style={'color': COLORS['green']}), 27 dash_table.DataTable( 28 id='top-songs-table', 29 columns=[{"name": i, "id": i} for i in top_songs.columns], 30 data=top_songs.nsmallest(10, 'Peak Position').to_dict('records'), 31 style_header={'backgroundColor': COLORS['green'], 'color': 'white'}, 32 style_cell={'textAlign': 'left'}, 33 style_data_conditional=[{'if': {'row_index': 'odd'}, 'backgroundColor': COLORS['light_red']}], 34 export_format='csv' 35 ) 36 ], style={'backgroundColor': COLORS['white'], 'padding': '20px', 'borderRadius': '10px'}) 37 ], style={'width': '60%', 'display': 'inline-block', 'verticalAlign': 'top'}), 38 39 html.Div([ 40 html.Div([ 41 html.H3('Seasonal Performance 🌟', style={'color': COLORS['green']}), 42 dcc.Graph(id='seasonal-chart') 43 ], style={'backgroundColor': COLORS['white'], 'padding': '20px', 'borderRadius': '10px', 'marginBottom': '20px'}), 44 45 html.Div([ 46 html.H3('Artist Comparison 🎤', style={'color': COLORS['green']}), 47 dcc.Dropdown( 48 id='artist-dropdown', 49 options=[{'label': artist, 'value': artist} for artist in df['performer'].unique()], 50 value=[df['performer'].iloc[0]], 51 multi=True, 52 style={'marginBottom': '10px'} 53 ), 54 dcc.Graph(id='artist-chart') 55 ], style={'backgroundColor': COLORS['white'], 'padding': '20px', 'borderRadius': '10px'}) 56 ], style={'width': '38%', 'display': 'inline-block', 'marginLeft': '2%'}) 57 ], style={'padding': '20px'}) 58])
Here, we defined containers for each visualization and interactive element, setting the stage for dynamic content updates.
Dash uses callbacks to empower our dashboard with interactivity — updating charts with user inputs, providing an unparalleled exploration experience.
We'll employ a callback function to link the dropdown selection to the three graphs requiring updates:
Python1from dash import callback, Input, Output 2 3@callback( 4 [Output('timeline-chart', 'figure'), 5 Output('seasonal-chart', 'figure'), 6 Output('artist-chart', 'figure')], 7 [Input('artist-dropdown', 'value')] 8) 9def update_charts(selected_artists): 10 # Timeline chart displaying number of songs per year 11 yearly_data = df.groupby('year').agg({'song': 'nunique', 'peak_position': 'min'}).reset_index() 12 timeline = px.line(yearly_data, x='year', y='song', title='Christmas Songs on Billboard Over Time') 13 timeline.update_traces(line_color=COLORS['red']) 14 15 # Seasonal average positioning by month 16 monthly_data = df.groupby(df['weekid'].dt.month)['week_position'].mean().reset_index() 17 seasonal = px.bar(monthly_data, x='weekid', y='week_position', title='Average Chart Position by Month') 18 seasonal.update_traces(marker_color=COLORS['green']) 19 seasonal.update_layout(yaxis_autorange='reversed') 20 21 # Artist performance over time 22 artist_data = df[df['performer'].isin(selected_artists)] 23 artist_perf = px.line(artist_data, x='weekid', y='week_position', color='performer', title='Artist Performance Over Time') 24 artist_perf.update_layout(yaxis_autorange='reversed') 25 26 return timeline, seasonal, artist_perf
Can you guess the output? Take your time to understand how this code works!
Let's look what we finally got at the end! While we've built many different features across the way and not all of them made it to the final preview (otherwise, the dashboard would be too big!), the version of the dashboard we have built in this lesson looks like this:
With any changes to the artist-dropdown
that we make, the dashboard updates the Timeline Chart with songs per year, the Seasonal Chart with monthly trends, and the Artist Chart with performance data based on the selected artists. It fully leverages the power of Dash to create a responsive and interactive dashboard.
Congratulations, you've completed building a fully interactive Christmas Songs Analytics Dashboard! By applying your knowledge of data visualization using Dash and Plotly, you've successfully combined various components and visualizations into an interactive project, allowing for versatile data exploration. Remember, practical exercises will let you further hone these skills, enabling you to tackle more complex dashboards and datasets with confidence in your future projects. Keep up the great work!