Part 3. Interactive Dashboards with Shiny for Python
From static maps to something people can click
In Part 2 you made choropleth maps of Auckland. They told a clear story, but the reader was stuck with whatever you chose: one time period, one classification, one colour scheme. If a colleague asked “what does it look like for just the central suburbs?”, your only option was to open the notebook and rerun the code.
Part 3 is about fixing that. You will learn how to build small web applications in pure Python that let other people filter, zoom, and compare the data themselves, in a browser, without installing anything.
The tool we will use is Shiny for Python.
What Shiny is, in one paragraph
Shiny is a Python package from Posit (the company behind RStudio) that turns a Python script into a web app. You write the interface (a slider, a dropdown, a map) and the logic (what to do when the slider moves) in Python, and Shiny handles the HTML, the CSS, the JavaScript, and the browser communication for you. It started as an R package in 2012, and the Python version follows the same ideas.
Why “reactive”? A small thought experiment
Imagine a council planner opens your dashboard. They pick “Waitematā” from a dropdown. Three things should update at once: a map zooms to that local board, a table refills with its suburbs, and a chart redraws showing the age distribution.
In a normal Python script you would have to write, in order: “when the dropdown changes, rerun the map function, then the table function, then the chart function, and do not forget the one you added last month”. Every new output means another line of wiring. Miss one, and the dashboard lies to the user.
Shiny flips this around. You describe what each output depends on, and Shiny works out when to run it. If the map reads input.local_board(), Shiny quietly remembers that link. When the dropdown changes, anything that reads it reruns, and nothing else does. This style is called reactive programming, and it is the single idea that makes dashboards tractable.
You will feel this working in Section 3.1. The jargon can wait until 3.3.
The three parts of every Shiny app
Every Shiny app, no matter how large, is built from three pieces:
- The UI, a Python expression that describes what the user sees (inputs and outputs).
- The server, a Python function that says how the outputs are computed from the inputs.
- The App object, which glues the two together so Shiny can run it.
from shiny import App, ui, render
app_ui = ui.page_fluid(
ui.h2("Hello Shiny"),
ui.input_slider("n", "Pick a number", 0, 100, 50),
ui.output_text("echo"),
)
def server(input, output, session):
@render.text
def echo():
return f"You picked {input.n()}"
app = App(app_ui, server)That is a complete, runnable app. Move the slider in your browser and the text below it updates. You did not write any code to detect the slider change, or to refresh the text. Shiny noticed that echo reads input.n(), and that is enough.
We will unpack every line of this in 3.1.
What you will build in Part 3
Part 3 runs across three weeks and follows a gentle ramp.
Week 6 covers the foundations: what a Shiny app looks like (3.1), how reactivity works once inputs and outputs start to multiply (3.2), and the decorators and UI pieces you will use most often (3.3).
Week 7, during the ANZAC break, is the main build week. You will deploy an app to the browser with shinylive (3.4) and bring real Auckland open data into it (3.5).
Week 8 is for polish, deployment, and submission. The full Assignment 2 brief lives in 3.6. Your dashboard is due Sunday 10 May, 23:59, live on GitHub Pages and publicly accessible.
Guest lecture
During Week 6, Alex Raichev (MRCagney) will talk about how transport-analytics dashboards are used in practice. A good chance to see where the skills you are picking up actually go in industry.
Assignment 2, at a glance
Throughout Part 3 you will work towards Assignment 2 (15% of the course mark, due Sunday 10 May 2026, 23:59, submitted via Canvas). It is a small Shiny dashboard that addresses one urban or transport question about Auckland.
You will be randomly assigned one of three data tracks on Tuesday 21 April 2026, 13:10 NZST:
- Track A: Public Transport, using Auckland Transport’s patronage data and bus/ferry layers.
- Track B: Commuter and Student flows, using Stats NZ’s 2023 Census data, with a required comparison between workers and students.
- Track C: Auckland crashes, using Auckland Transport’s crash records.
The dashboard must include at least three user inputs, one interactive ipyleaflet map, one quantitative chart (Plotly or matplotlib), and a shinylive deployment on GitHub Pages. A short design report (under 4 pages, PDF rendered from Quarto) accompanies the code. Full brief, rubric, and deliverables in 3.6.
Prerequisites
Before starting 3.1, you should be comfortable with:
- Python basics: variables, functions, loops, conditionals.
- pandas: filtering, grouping, merging DataFrames.
- GeoPandas: reading spatial files, basic geometric operations.
- Making a static map with matplotlib or
foliumipyleaflet.
If any of these feel shaky, revisit Part 2 before moving on. Shiny adds a new layer on top of what you already know; it does not replace it.
Type the code. Do not copy-paste. Shiny’s error messages are cryptic at first, and the quickest way to build intuition is to break a working example and watch what goes wrong.