How to Create Interactive Time Series Visualizations in Python with Plotly

How to Create Interactive Time Series Visualizations in Python with Plotly
Image by Author | Piktochart

Plotly is a library compatible with multiple programming languages and platforms that facilitates the creation of interactive, high-quality visualizations. Visualizing time series data with Plotly pushes the boundaries of interactivity and clarity, making it easier to explore trends, patterns, and relationships, and draw actionable insights from data.

This article shows how to build interactive visualizations for time series data using Plotly in Python.

Step-by-Step Process

We start as usual by importing the necessary modules.

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

Plotly’s px (standing for ‘Plotly Express’) and graph_objects components provide built-in support for efficient and intuitive plotting, and a fine-grained API for low-level customization, respectively. We will explore both, but first, we load and prepare the time series data to visualize, including a more convenient renaming of key columns.

url = "https://raw.githubusercontent.com/gakudo-ai/open-datasets/refs/heads/main/CTA_-_Ridership_-_Daily_Boarding_Totals.csv"
df = pd.read_csv(url)

df['service_date'] = pd.to_datetime(df['service_date'])
df.rename(columns={'bus': 'Bus Rides', 'rail_boardings': 'Train Rides'}, inplace=True)

data = df[['service_date', 'Bus Rides', 'Train Rides']]

Based on Plotly Express, our first interactive visualization will be a line chart (px.line()) with separate facets for bus and train rides. The goal of this visualization is to facilitate visual comparison of daily rides between both means of transportation.

The logical steps in this process are: to reshape the data (necessary for later arranging the two time series into a single line plot), create the line plot, adjust the faceted layout, and show the resulting visualization.

melted_data = data.melt(id_vars='service_date', 
                        value_vars=['Bus Rides', 'Train Rides'], 
                        var_name='Transportation Mode', 
                        value_name='Number of Rides')

fig = px.line(
    melted_data,
    x='service_date',
    y='Number of Rides',
    color='Transportation Mode',
    facet_row='Transportation Mode',
    title="Interactive Line Chart: Bus and Train Rides Over Time",
    labels={'service_date': 'Date', 'Number of Rides': 'Number of Rides'},
    template='plotly_dark',
)

fig.update_layout(
    xaxis_title="Date",
    yaxis_title="Number of Rides",
    legend_title="Transportation Mode",
    height=600,
    margin=dict(l=50, r=50, t=50, b=50),
)

fig.show()

The result is an interactive chart like this:

Interactive time series line plot

Try different actions like a gentle horizontal drag with the cursor on the plot, to zoom in on a specific period:

Zooming in an interactive plot

We will now create a stacked bar chart to represent the daily total of bus and train rides jointly (note: this information is available in the original dataset, but we are pretending it is not for illustration purposes). This time we will show how to create it with graph_objects or go for short, concretely with the class go.Figure().

data['Total Rides'] = data['Bus Rides'] + data['Train Rides']
fig = go.Figure()

Once the object that contains the plot is initialized, we add the two sets of bars to display as follows.

fig.add_trace(go.Bar(
    x=data['service_date'],
    y=data['Bus Rides'],
    name='Bus Rides',
    marker_color='blue',
))

fig.add_trace(go.Bar(
    x=data['service_date'],
    y=data['Train Rides'],
    name='Train Rides',
    marker_color='red',
))

Next, we also add a line trace that will complement the stacked bars to highlight total rides.

fig.add_trace(go.Scatter(
    x=data['service_date'],
    y=data['Total Rides'],
    mode='lines+markers',
    name='Total Rides',
    line=dict(color='green', width=2),
))

We are now ready to set up the layout. Here, it is important to use the option barmode=’stack’ to have both sets of bars stacked.

fig.update_layout(
    title="Interactive Stacked Bar Chart with Total Rides",
    xaxis=dict(
        title="Date",
        rangeslider=dict(visible=True),
        type="date",
    ),
    yaxis_title="Number of Rides",
    barmode='stack',
    template='plotly_white',
)

fig.show()

The result (since we are using a very large time period, you may need to significantly zoom in enough to see it more clearly):

Interactive stacked bar chart

Simply hovering with the cursor will allow you to interactively display specific values for bus rides, train rides, and total rides.

That’s it! With these two examples, we explained how to build interactive time series data visualizations in Python using Plotly.

Leave a Reply

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