Skip to content

Insights at a Glance: The Step-by-Step Process to Create an Interactive Hospitality Manager Dashboard using Python and Dash

Data paralysis is a nightmare.

It leads to only two outcomes:

  • poor decision-making
  • missed opportunities

Instead, decision-makers need real insights at their fingertips. And you can help bring those insights to life by creating interactive dashboards.

Manual data crunching wastes valuable time.

There’s a better way to handle complex data. Turning massive amounts of data into meaningful dashboards that are visually appealing and easy to use. The best part is that it can be done using free tools: Python and Dash. And you don’t have to install anything, either.

Imagine what this means for you:

  • making fast decisions with real-time custom dashboards
  • keep up with the latest and greatest data management tools
  • reclaim your time and impress your coworkers (and your boss!)

Your step-by-step guide to getting it done

This tutorial walks you through creating an interactive dashboard with Python and Dash.

This kind of thing is PERFECT for a data analytics portfolio project. And it will work for any dataset or industry. Even yours. If you’re using Excel for reports and dashboards today, give Python a chance.

Don’t sleep on the power of automating your data analytics work!

Here’s what we’re building today (click here if you can’t see the gif below)

Alright, let’s create this thing.

Step 1: Set Up Your Environment

First, prepare your Google Colab environment by installing the necessary libraries.

Paste this code into a new Google Collab notebook cell and run it.

You can use my notebook to help you get started.

!pip install dash pandas plotly
import dash
import pandas as pd
import plotly.express as px
from dash import dcc, html, Input, Output

# Better image quality
%config InlineBackend.figure_formats = 'retina'

Step 2: Load and Inspect Data

Load your CSV file and get a feel for how it’s built and what’s inside.

By the way, we’re using the Hospitality data set from the fantastic Real World, Fake Data project (thanks Mark!)

# Load the dataset
file_path = 'https://query.data.world/s/6whyevrn7zfjrm2rvvydbskslxexex?dws=00000'
data = pd.read_csv(file_path)

# Display the first few rows
print(data.head())

Step 3: Data Cleaning and Preparation

Before diving into Dash, let’s clean and prepare the data for analysis.

  • Convert date columns from strings to datetime objects
  • Fill in missing values
  • Calculate new columns for “total guests” and “revenue”
  • Remove duplicate records
  • Filter data to only “Completed” reservations

Here’s the code:

# Convert date columns to datetime and sort by date
data['check_in_date'] = pd.to_datetime(data['check_in_date'])
data['Date'] = pd.to_datetime(data['Date'])
data.sort_values('Date', inplace=True)

# Deal with missing entries and create new features
data.fillna({'special_requests_flag': 'No', 'advanced_booking': 'No'}, inplace=True)
data['total_guests'] = data['adults'] + data['children']
data['revenue'] = data['Avg Room Rate'] * data['stay_duration']

# Eliminate redundant records
data.drop_duplicates(inplace=True)

# Focus on 'Completed' reservations
data = data[data['reservation_status'] == 'Completed']

Step 4: Create Interactive Plots

Now that we have a good sense of the data let’s use Plotly to create interactive visualizations of your data.

We’re creating 4 charts for the dashboard:

  1. Daily Revenue
  2. Reservation Status
  3. Booking Channel Usage
  4. Guest Composition

These 4 charts will give managers quick insights into the most important parts of their business.

# Daily Revenue
daily_revenue = data.groupby('Date')['revenue'].sum().reset_index()
revenue_fig = px.line(daily_revenue, 
                      x='Date', 
                      y='revenue', 
                      title='Daily Revenue')

# Reservation Status Count
status_count_fig = px.bar(data, 
                          x='Date', 
                          y='reservation_id',
                          color='reservation_status', 
                          title='Daily Reservation Status Count')

# Booking Channel Usage
channel_fig = px.area(data, 
                      x='Date', 
                      y='reservation_id',
                      color='booking_channel', 
                      title='Daily Booking Channel Usage')

# Guest Composition
comp_fig = px.scatter(data, 
                      x='Date', 
                      y='total_guests', 
                      size='stay_duration', 
                      color='room_type', 
                      title='Daily Guest Composition')

# Customize the charts with a clean and professional look
for fig in [revenue_fig, status_count_fig, channel_fig, comp_fig]:
    fig.update_layout(plot_bgcolor='white', paper_bgcolor='white')
    fig.update_xaxes(title_standoff=25)
    fig.update_yaxes(title_standoff=25)

Step 5: Build Your Dashboard

Now that we have our charts and graphs (Plotly calls these ‘figures’), let’s assemble the pieces into an interactive dashboard using Dash.

This might seem like a lot of code, but a lot of it is styling so that our final product looks awesome.

Let’s add one for each graph to update our dashboard based on the start and end date that the user chooses:

app = dash.Dash(__name__)

# Dashboard layout with custom styling
app.layout = html.Div([
    html.H1("Hospitality Management Dashboard", 
            style={'text-align': 'center', 'color': '#007BFF'}),

    html.Div([
        html.P("Select Date Range:"),
        dcc.DatePickerRange(
            id='date-picker-range',
            start_date=data['Date'].min(),
            end_date=data['Date'].max(),
            display_format='MMM D, YYYY',
            style={'margin-bottom': '20px'}
        ),
    ], style={'text-align': 'center'}),

    html.Div(dcc.Graph(id='revenue-graph'), style={'padding': '10px'}),
    html.Div(dcc.Graph(id='reservation-count-graph'), style={'padding': '10px'}),
    html.Div(dcc.Graph(id='channel-count-graph'), style={'padding': '10px'}),
    html.Div(dcc.Graph(id='guest-count-graph'), style={'padding': '10px'})
], style={'font-family': 'Arial, sans-serif', 'margin': '20px'})

# Callbacks to update graphs based on selected date range
@app.callback(
    [Output('revenue-graph', 'figure'),
     Output('reservation-count-graph', 'figure'),
     Output('channel-count-graph', 'figure'),
     Output('guest-count-graph', 'figure')],
    [Input('date-picker-range', 'start_date'),
     Input('date-picker-range', 'end_date')]
)
def update_graphs(start_date, end_date):
    # Filter data based on the date range
    filtered_data = data[(data['Date'] >= start_date) & (data['Date'] <= end_date)]

    # Daily Revenue
    revenue_fig = px.line(filtered_data.groupby('Date')['revenue'].sum().reset_index(),
                          x='Date', y='revenue', title='Daily Revenue')

    # Daily Room Type Reservation Counts
    reservation_count_data = filtered_data.groupby(['Date', 
                                                    'room_type']).size().reset_index(name='count')
    reservation_count_fig = px.bar(reservation_count_data, 
                                   x='Date', y='count', color='room_type',
                                   title='Daily Reservation Counts by Room Type', text='count')

    # Daily Booking Channel Counts
    channel_count_data = filtered_data.groupby(['Date', 
                                                'booking_channel']).size().reset_index(name='count')
    channel_count_fig = px.area(channel_count_data, 
                                x='Date', y='count', color='booking_channel',
                                title='Daily Booking Channel Counts')

    # Daily Property Guest Counts
    guest_count_data = filtered_data.groupby(['Date', 'Property']).sum().reset_index()
    guest_count_fig = px.bar(guest_count_data, x='Date', y='total_guests', color='Property',
                             title='Daily Guest Counts by Property', text='total_guests')

    # Customize the figures
    for fig in [revenue_fig, reservation_count_fig, channel_count_fig, guest_count_fig]:
        fig.update_layout(plot_bgcolor='white', paper_bgcolor='white')
        fig.update_xaxes(title_standoff=25)
        fig.update_yaxes(title_standoff=25)

    return revenue_fig, reservation_count_fig, channel_count_fig, guest_count_fig

Step 6: Launch and Share

Finally, let’s run our app! Add this at the end of your notebook:

# Run the app
if __name__ == '__main__':
    app.run_server(debug=True)

Here’s what you’ll see in Google Colab: (click here if you can’t see the gif below)

Looks great!

Try it on your own:

  • Try different chart types
  • Use the same chart types but use different columns
  • Try it with a data set from your work or another project

Leave a Reply

Your email address will not be published. Required fields are marked *