Brick by Brick: Build a multi-page dashboard
Part 2: This is the second installment of a multi-part series on incrementally building a dashboard using Plotly Dash. We create a spatial data scatter plot using Folium.
The data from Inside AirBnB provides publicly available data for AirBnB listings in Seattle, USA. We will use the dashboard framework we created in the first part of this series and include spatial data to explore the locations of the listings
GOAL
We are aiming for a dashboard layout as seen below. We will add iFrames to our layout to display Folium maps. These maps are interactive, with hover tooltips that provide more details about each point. On the left we have each point representing a listing. On the right the map shows the aggregate count of listings for neighborhoods within Seattle.
Note: The maps are static (.html files) in this article and will respond dynamically to the filters on the left in the next article. But as can be seen below, they allow for interactivity with features such as zooming, panning and tooltips.
INSTALLATIONS
Follow along the instruction in this Medium article to set up and run the Dash app server from Jupyter notebook. The notebook in Github also lists the packages used as well as their versions to help you get going.
CODE AND DOWNLOADS
The code for this series can be found at this Github repo. The application is run from Jupyter notebook. There are .py (Python) files that will contain code for the layout and data manipulation. I used, and highly recommend, Visual Studio Code for working with these as there are a number of handy extensions available for formatting that is particularly helpful to build the HTML DOM structure and coding in Python.
The files used to create the dashboard with the maps are:
Notebook:
CreateDashboardSpatial.ipynb
.py files :
layout_spatial.py
datamanipulation_spatial.py
callback_spatial.py
.html files:
IndvListingsMap.html
NeighborhoodCountMap.html
FOLDER STRUCTURE
CHANGES IN THE NOTEBOOK -CreateDashboardSpatial.ipynb
If you have arrived here from Part 1 of the series, the only change to be made in the notebook, is the name of the layout python file. The layout will now include the html div displaying the maps and so we import all functions from within layout_spatial.py (instead of layout_scaffolding.py) .
The changes to be made to the layout in layout_spatial.py are rendered remarkably easy with the modularization of creation of HTML document elements.
For instance we create a function get_mapcol that takes the name of an HTML file and displays it in an html.Div. We can now reuse this html.Div and change the name of the file for various kinds of spatial data. The entire Div is a six column (Bootstrap) element and can be included in a row in the page.
Inline frame tags-html.iFrame - open up a myriad possibilities in embedding documents within the current HTML document. While in this exercise we are embedding static HTML pages in designated spots, this tag allows for videos, and other interactive media to be placed within a page. As we move onto understanding Dash Core Components better in the next article in this series, we will update the HTML being displayed when the user selects an item in the filter, that will lead to narrowing down the neighborhood of Seattle they they are interested in.
The HTML maps themselves were generated using Folium. You can peek into the code that generated these maps in callbacks_spatial.py. But first let’s see what serves up the data for these maps.
This brings us to the datamanipulation_spatial.py file. The Inside AirBnB data that is being displayed in these maps is found in the listings_1.csv file that was extracted out (using 7zip) of the listings.csv.gs file downloaded from the website. Pandas function read_csv reads in this CSV data into the dataframe full_df which we will copy into rental_geo_df specific dataframe for the spatial data. This data, that was scraped from the web, is cleaner than most data handed to analysts. The spatial data we are interested in is mainly the latitude and longitude to locate the listing on a Folium map. We also grab the “price” and names of the neighborhoods so we can offer tooltip information as the user hovers over the listings in the map.
A manipulation of interest is the creation of the column glow_marker_color. I have selected a “neon” color for each of the seventeen “neighborhood groups” within Seattle and placed it in an array. We now want to assign these colors to the neighborhood group they were chosen for.
glow_group_color = dict(zip(
list(rental_geo_df.groupby(
"neighbourhood_group_cleansed").groups.keys()),
glow_color_list))rental_geo_df["glow_marker_color"] = rental_geo_df["neighbourhood_group_cleansed"].map(glow_group_color)
We group the dataframe by these neighborhood groups and then access the names of the groups using groups.keys () which can then be converted to a list. We then zip the color list with the neighborhood list and create a dictionary that can be used to create a new column in the dataframe using the “map” function. Pretty handy, huh?
Another manipulation of interest is the creation of an aggregate count for the neighborhood-wide listing aggregation count. We also normalize(scale it to a number between 0 and 1) the count of listings in a neighborhood. This column will then be used to size the circle displaying the count of listings for each neighborhood on the map.
Armed with the dataframes created in the datamanipulation_spatial.py file, we can run the function createRentalMap and createListingSpatial in the callbacks_spatial.py file. More on the details about these functions in the next section.
Concept
Folium builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js library. Manipulate your data in Python, then visualize it in on a Leaflet map via Folium.
Folium makes it easy to visualize data that’s been manipulated in Python on an interactive Leaflet map. It enables both the binding of data to a map for choropleth visualizations as well as passing Vincent/Vega visualizations as markers on the map.
Folium has several tile options that you can read about here. The initialization is performed with our choices of a dark background and a light background and the location centering is calculated using the mean of the latitude and longitude of the Seattle dataset.
We can then call the plotDot function that utilizes Folium’s CircleMarkers to create a scatter plot on the map. Addition of Tootltips, Popups and other child elements add additional information to the visualization. Every point “CircleMarker” is added to the map element created above and once all the elements are added, the map can be saved using map.save(filename)
Note: Since the static HTML has been created for you, you will not need to run these functions. They will be heavily utilized with the implementation of filtering coming up in the series.
And Finally
Run the notebook using Kernel -> Restart & Run all ..
You will receive a link to run the application that you can interact with.
Dash is running on http://<localhost IPAddress>:8050/
Feel free to comment, question and reach out.