This interactive crime dashboard visualizes annual crime data from 1975 to 2015 across major North American cities, enabling users to explore long-term trends and geographic patterns in public safety. Its central feature is an interactive, geocoded map that allows users to examine various crime rates by city. Together in combination with additional visualization, the tools populating this dashboard provide a data-driven, temporal view of how crime has evolved across North America.
| Environment | Purpose | URL |
|---|---|---|
| Main (Production) | Stable version for public viewing | View Live Dashboard |
| Development | Testing new features and map logic | View Dev Version |
The dashboard includes an AI-powered tab that lets users query the crime dataset using natural language, powered by querychat and Anthropic's Claude.
Features:
- Natural language chat interface to filter and explore crime data
- Reactive data table showing filtered results
- Two interactive Altair visualizations (crime trend over time + city comparison bar chart)
- Download button to export the filtered dataset as CSV
API Key Setup:
The AI tab requires an Anthropic API key to function.
- Create a
.envfile in the project root:
ANTHROPIC_API_KEY=your-key-here
- Make sure
.envis listed in.gitignore(never commit your key). - For deployment on Posit Connect Cloud, set
ANTHROPIC_API_KEYas an environment variable in the deployment settings.
- Clone the repository
git clone https://github.com/UBC-MDS/DSCI-532_2026_38_crime-dashboard.git
cd DSCI-532_2026_38_crime-dashboard
- Create and activate environment
conda env create -f environment.yml
conda activate crime-dashboard
- Run the app
python -m shiny run --reload src/app.py
Make sure your environment is activated, then from the project root:
pytest tests/test_utils.py -vThe app must be running locally before executing UI tests.
Terminal 1 — start the app:
python -m shiny run --reload src/app.pyTerminal 2 — run the tests:
playwright install chromium
pytest tests/test_ui.py -v| Test | File | What it verifies |
|---|---|---|
test_get_crime_column_valid |
test_utils.py |
Valid crime types map to the correct DataFrame column |
test_get_crime_column_none_string |
test_utils.py |
"None" selection returns None so KPI placeholders show correctly |
test_get_crime_column_unknown |
test_utils.py |
Unrecognized inputs return None without crashing |
test_app_loads_with_tabs |
test_ui.py |
App starts and both tabs are visible |
test_crime_type_selection_updates_kpis |
test_ui.py |
Selecting a crime metric updates the KPI cards |
test_reset_button_clears_crime_type |
test_ui.py |
Reset button restores crime type to "None" |
If you would like to use this environment with Jupyter notebooks, register the kernel with:
python -m ipykernel install --user --name crime-dashboard --display-name "Python (crime-dashboard)"
jupyter lab
Contributor Instructions: https://github.com/UBC-MDS/DSCI-532_2026_38_crime-dashboard/blob/main/CONTRIBUTING.md
