Most examples work across multiple plotting backends equivalent, this example is also available for:
import numpy as np
import pandas as pd
import holoviews as hv
hv.extension("bokeh")
Let's dive into a concrete example, namely the New York - Taxi Data (For-Hire Vehicle (“FHV”) records). The following data contains hourly pickup counts for the entire year of 2016.
Considerations: Thinking about taxi pickup counts, we might expect higher taxi usage during business hours. In addition, public holidays should be clearly distinguishable from regular business days. Furthermore, we might expect high taxi pickup counts during Friday and Saturday nights.
Design: In order model the above ideas, we decide to assign days with hourly split to the radial segments and week of year to the annulars. This will allow to detect daily/hourly periodicity and weekly trends. To get you more familiar with the mapping of segments and annulars, take a look at the following radial heatmap:
# load example data
df_nyc = pd.read_csv("../../../assets/nyc_taxi.csv.gz", parse_dates=["Pickup_date"])
# create relevant time columns
df_nyc["Day & Hour"] = df_nyc["Pickup_date"].dt.strftime("%A %H:00")
df_nyc["Week of Year"] = df_nyc["Pickup_date"].dt.strftime("Week %W")
df_nyc["Date"] = df_nyc["Pickup_date"].dt.strftime("%Y-%m-%d")
heatmap = hv.HeatMap(df_nyc, ["Day & Hour", "Week of Year"], ["Pickup_Count", "Date"])
At first glance: First, let's take a closer look at the mentioned segments and annulars. Segments correspond to hours of a given day whereas annulars represent entire weeks. If you use the hover tool, you will quickly get an idea of how segments and annulars are organized. Color decodes the pickup values with blue being low and red being high.
Plot improvements: The above plot clearly shows systematic patterns however the default plot options are somewhat disadvantageous. Therefore, before we start to dive into the results, let's increase the readability of the given plot:
yticks=None
.xticks=("Friday", ..., "Thursday")
xmarks=7
.start_angle=np.pi*19/14
. The default order is defined by the global sort order which is present in the data. The default starting angle is at 12 o'clock.Let's see the result of these modifications:
xticks = ("Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday")
heatmap.opts(
radial=True, start_angle=np.pi*19/14, width=600, height=600,
yticks=None, xticks=xticks, xmarks=7, ymarks=3)
After tweaking the plot defaults, we're comfortable with the given visualization and can focus on the story the plot tells us.
There are many interesting findings in this visualization: