3.6. Assignment 2: Your Dashboard
This is the brief for Assignment 2. It mirrors the official version on Canvas (which is the source of truth if anything here ever drifts). Read it end to end before you start coding.
| Assessment type | Individual assignment |
| Weighting | 15% of the course mark |
| Coverage | Weeks 6-8 (Shiny for Python) |
| Due date | Week 8, Sunday 10 May 2026, 23:59 NZST |
| Submission | Via Canvas |
| Late penalty | 10% per calendar day, unless a formal extension has been approved |
- Implementing reactive programming with Shiny for Python.
- Integrating geospatial data into an interactive application.
- Deploying a browser-based app using shinylive on GitHub Pages.
- Communicating technical design decisions clearly.
Your final app must run fully in the browser, via your own GitHub Pages site.
Part A: Topic and application scope
Your dashboard must address a meaningful urban or transport-related question about Auckland. Do not treat it as just an assignment. Treat it as a small tool you could show someone to explain a societal problem.
Themes you might consider:
- Congestion explorer
- Public transport accessibility
- Built environment
- Casualties
You do not pick your track. On Tuesday 21 April 2026, 13:10 NZST, each student will be randomly assigned to one of the three data tracks below. Read all three before the assignment happens so you are not surprised. Your assigned track determines the core dataset you must use.
The three data tracks
Each track is built around a single, well-documented Auckland dataset. These are the same three shapes of data you met in 3.5 (points, lines, polygons).
Track A: Public Transport
Core dataset: Auckland Transport patronage and spatial service data.
- Patronage (required): AT Data Sources. Use the patronage time series to show how bus, train, or ferry use changes over time.
- Bus stops (points): Bus service, layer 3
- Bus routes (lines): Bus service, layer 2
- Ferry routes (lines and points): Ferry service, layer 1
What you must show: a map of the network (stops or routes) paired with a chart of patronage over time. At least one input should let the user cut the patronage series by mode, route, or period.
Example questions:
- How has patronage recovered after the pandemic, and does the pattern differ by mode?
- Which bus routes or ferry routes carry the most passengers, and how has their share changed?
Track B: Commuter and Student flows (OD comparison)
Core dataset: Stats NZ’s 2023 Census commuter AND student datasets.
- 2023 Census commuter dataset (people travelling to work).
- The matching student dataset on the same Stats NZ portal (people travelling to study).
What you must show: a side-by-side comparison of commuter flows and student flows on the same geography (SA2 or higher). A reader should be able to see, for a chosen origin or destination, how the two populations move differently.
Example questions:
- Which SA2 areas have the biggest gap between workers’ and students’ destinations?
- Are students’ journeys shorter or longer than workers’, and where does this reverse?
- Which suburbs export mostly commuters, mostly students, or both?
Track C: Auckland crashes
Core dataset: Auckland Transport crash data.
What you must show: a map of crash locations (points) with at least one filter that changes what is visible (severity, year, mode involved, time of day). The quantitative chart should show crash counts broken down by one attribute.
Example questions:
- Which intersections or corridors have the highest concentration of serious crashes?
- How do crash patterns change between day and night, or weekday and weekend?
- Where are pedestrian or cyclist crashes concentrated, and how does this align with the strategic cycling network?
Part B: Technical requirements
B1. Minimum 3 user inputs
Your app must include at least three user inputs, chosen from:
- Dropdown menus (
ui.input_select,ui.input_selectize) - Sliders (
ui.input_slider) - Checkboxes (
ui.input_checkbox,ui.input_checkbox_group) - Radio buttons (
ui.input_radio_buttons) - Date selectors (
ui.input_date,ui.input_date_range)
Inputs must meaningfully change the visual outputs. A slider that is read by nothing will not count.
B2. Reactivity (required functions)
Your server function must demonstrate correct reactive programming. At minimum, we expect to see:
1. At least one @reactive.calc that is shared between two or more outputs. This is the canonical way to filter or transform data once, reactively, and then feed several outputs from the same result. Example:
@reactive.calc
def filtered():
df = parks[parks["area_ha"] >= input.min_area()]
if input.suburb() != "All":
df = df[df["suburb"] == input.suburb()]
return dfBoth the map output and the chart output should then read filtered(), so the filter runs once per input change, not twice.
2. At least one @render.* decorator for each output. Pick the decorator that matches the output type:
| Output you want | Decorator |
|---|---|
| Text summary | @render.text |
| Plotly / matplotlib | @render.plot |
| Interactive DataFrame | @render.data_frame |
| Static table | @render.table |
| ipyleaflet map | @render_widget (from shinywidgets) |
3. Recommended: one @reactive.event or @reactive.effect. Use @reactive.event to gate an expensive calculation behind a button (e.g. “Recompute” or “Apply filters”), and @reactive.effect for side effects that do not return a value (e.g. logging, or calling ui.update_* to change another input). Example:
@reactive.effect
@reactive.event(input.reset)
def _():
ui.update_slider("min_area", value=0)
ui.update_select("suburb", selected="All")4. Avoid redundant computation. If two outputs both filter parks directly on input.min_area(), the filter runs twice on every slider move. Wrap it in a @reactive.calc once, and read that calc from both.
See 3.2 (Reactivity in Action) and 3.3 (Decorators and UI Polish) for the full reference. Marks under “Reactivity” in the rubric will look for these patterns specifically.
Part C: Visualisations (minimum 2 types)
Your dashboard must include the following two outputs at minimum.
1. One interactive map. You must use ipyleaflet wrapped in Shiny via shinywidgets (see 3.4). Static matplotlib maps, folium maps, and Plotly maps do not satisfy this requirement, because folium does not run in shinylive and static maps are not interactive. The map must:
- Be rendered with
ipyleafletand@render_widgetfromshinywidgets. - Display spatial data (points, polygons, or flows).
- Update reactively when inputs change.
- Use an appropriate basemap and layer styling.
2. One quantitative chart. Use Plotly or matplotlib to show patterns such as:
- A time series
- A bar chart
- A flow comparison
- A distribution plot
Optional extras (summary tables, heatmaps, additional charts) are welcome and rewarded under “polish”.
Part D: User interface design
Your layout must be:
- Clean and logically organised.
- Clearly labelled.
- Readable without clutter.
- Functional at desktop width.
Include short help text explaining how to use the dashboard. A one-paragraph “how to read this” card on the main page is enough.
Data requirements
You must:
- Use publicly available Auckland-related data.
- Document all sources and licensing in the README and the design report.
- Clean and validate the data before use (handle missing values, check units).
- Handle coordinate reference systems correctly (most Auckland datasets are NZTM 2193; ipyleaflet needs WGS84, EPSG:4326).
All data required to run the deployed app must be accessible via your repository or via stable public links.
shinylive bundles every file in your app folder down to every visitor’s browser. Simplify polygons, drop unused columns, and save as GeoPackage (.gpkg) where possible. You saw the pattern in 3.5.
Deployment (mandatory)
You must deploy your application using shinylive on GitHub Pages.
- App runs fully client-side in the browser.
- No server required.
- Hosted on your own GitHub Pages site.
- Publicly accessible, no login required.
Your deployed URL should follow the pattern:
https://<your-username>.github.io/<your-repo>/
The deployed app must:
- Load without errors.
- Render initial outputs within a reasonable time.
- Respond correctly to all interactive controls.
If the deployed app does not run, marks for functionality and deployment will be significantly reduced.
Design report (under 4 pages, PDF only, rendered from Quarto)
Submit a structured design report as a PDF, rendered from a Quarto document (.qmd → .pdf). We want both the source .qmd in your repo and the rendered .pdf uploaded to Canvas. Word (.docx) is not accepted.
# From your repo root, after writing report.qmd
quarto render report.qmd --to pdfMinimal YAML header for the report:
---
title: "GISCI 343 Assignment 2: Design Report"
author: "Your Name (UPI)"
date: today
format:
pdf:
documentclass: article
geometry: margin=2.5cm
fontsize: 11pt
number-sections: true
toc: false
---Section headings to use (in order):
1. Motivation and audience. What problem does your dashboard address? Who is it for? What decision or insight does it enable?
2. Data and preparation. Datasets used, variables, coverage, and cleaning steps. Limitations and coordinate-reference-system considerations.
3. Technical architecture. App structure, reactive dependency logic (inputs → calculations → outputs), key functions or classes, performance considerations. Include a simple diagram of the reactive structure (a Mermaid diagram rendered inside Quarto is ideal).
4. User interface walkthrough. Three to four screenshots. Explain how a user interacts with the app from start to insight.
5. Limitations and future improvements. Constraints you hit and how you would extend the app with more time.
Mermaid diagrams render cleanly in Quarto’s PDF output via the built-in Mermaid support. A small reactive-dependency diagram for your app counts towards the “Technical architecture” section.
shinylive ships every file in your app folder down to every visitor’s browser. Do not include anything you would not put on a public website. If your data contains personal information, aggregate before bundling.
Deliverables
Submit the following via Canvas.
1. GitHub repository URL. Repository must include:
- Complete Shiny app code.
- A README with setup and deployment instructions.
- A
requirements.txtorpyproject.toml. - Data preparation scripts (the code you used to clean and simplify your data).
2. Deployed application URL. Your working GitHub Pages link.
3. Design report (PDF, rendered from Quarto). Upload the rendered PDF to Canvas, and commit the source report.qmd to your repository. File-name format for the PDF, exactly:
GISCI343_A2_DesignReport_YourLastName_YourUPI.pdf
Marking rubric
| Criterion | Weight | Notes |
|---|---|---|
| Question and framing | 10% | Specific, defensible, documented in the report |
| Data and methods | 20% | Clean inputs, sensible indicators, reproducible from the repo |
| Reactivity | 20% | Correct use of @reactive.calc and inputs; no redundant computation |
| Map and visual design | 20% | Readable map, sensible colours, legend or labels, chart is informative |
| Deployment | 15% | Live URL, app loads in reasonable time, all controls respond |
| Design report | 10% | Clear, under 4 pages, covers the five sections above |
| UI polish and documentation | 5% | Clean layout, help text, README explains what/why/how/limits |
Timeline
| Week | Date | Goal |
|---|---|---|
| 6 | Before 21 April | Read all three tracks. Get a “hello world” Shiny app deployed to GitHub Pages. |
| 6 | 21 April, 13:10 | Random track assignment announced on Canvas. Start scoping your question against your assigned dataset. |
| 7 | 27 April - 3 May | Build the data pipeline, the map, and the chart. Get three inputs wired up. Push your first real commit. |
| 8 | 4 May - 10 May | Polish the UI, write the design report in Quarto, render it to PDF, submit via Canvas. |
Academic integrity
This assignment must be your own work. You may consult course materials, PyShiny documentation, and seek clarification from instructors or tutors. You may not:
- Copy application code or design from peers or online sources without attribution.
- Submit work that has been submitted for another course.
Any breaches of academic integrity will be addressed under the University of Auckland’s Student Conduct procedures and may result in a zero grade or further disciplinary action.
What you have learned (across Part 3)
By the end of Part 3 you can:
- Explain reactive programming and why a Shiny app needs it.
- Build a multi-page Shiny dashboard with a sidebar, a card, inputs, a map, and a chart.
- Use
@reactive.calcfor the right jobs. - Deploy an app via shinylive to a public URL on GitHub Pages.
- Bring real Auckland open data (transport patronage, commuter/student flows, crash records) into a dashboard.
That is enough to put a dashboard on your portfolio. Pick a question you are curious about, and go build it.
Further reading
- Posit, Shiny for Python (official docs).
- Posit, shinylive (for deployment).
- Auckland Transport Data Sources (patronage and more)
- Auckland Transport GIS (bus, ferry, assets)
- Where crashes are happening in Auckland
- Stats NZ Data Finder