lmiranda eee015efac
Some checks failed
CI / lint-and-test (push) Has been cancelled
fix: Load .env in amenity_radar notebook for database credentials
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 20:43:43 -05:00

Analytics Portfolio

CI

Live Demo: leodata.science

A personal portfolio website showcasing data engineering and visualization capabilities, featuring an interactive Toronto Neighbourhood Dashboard.

Live Pages

Route Page Description
/ Home Bio landing page
/about About Background and experience
/projects Projects Portfolio project showcase
/resume Resume Professional CV
/contact Contact Contact form
/blog Blog Technical articles
/blog/{slug} Article Individual blog posts
/toronto Toronto Dashboard Neighbourhood analysis (5 tabs)
/toronto/methodology Methodology Dashboard data sources and methods
/health Health API health check endpoint

Toronto Neighbourhood Dashboard

An interactive choropleth dashboard analyzing Toronto's 158 official neighbourhoods across five dimensions:

  • Overview: Composite livability scores, income vs safety scatter
  • Housing: Affordability index, rent trends, dwelling types
  • Safety: Crime rates, breakdowns by type, trend analysis
  • Demographics: Income distribution, age pyramids, population density
  • Amenities: Parks, schools, transit accessibility

Data Sources:

  • City of Toronto Open Data Portal (neighbourhoods, census profiles, amenities)
  • Toronto Police Service (crime statistics)
  • CMHC Rental Market Survey (rental data by zone)

Architecture

flowchart LR
    subgraph Sources
        A1[City of Toronto API]
        A2[Toronto Police API]
        A3[CMHC Data]
    end

    subgraph ETL
        B1[Parsers]
        B2[Loaders]
    end

    subgraph Database
        C1[(PostgreSQL/PostGIS)]
        C2[dbt Models]
    end

    subgraph Application
        D1[Dash App]
        D2[Plotly Figures]
    end

    A1 & A2 & A3 --> B1 --> B2 --> C1 --> C2 --> D1 --> D2

Pipeline Stages:

  • Sources: External APIs and data files (City of Toronto, Toronto Police, CMHC)
  • ETL: Python parsers extract and validate data; loaders persist to database
  • Database: PostgreSQL with PostGIS for geospatial; dbt transforms raw → staging → marts
  • Application: Dash serves interactive dashboards with Plotly visualizations

For detailed database schema, see docs/DATABASE_SCHEMA.md.

Quick Start

# Clone and setup
git clone https://gitea.hotserv.cloud/lmiranda/personal-portfolio.git
cd personal-portfolio

# Install dependencies and configure environment
make setup

# Start database
make docker-up

# Initialize database schema
make db-init

# Run development server
make run

Visit http://localhost:8050 to view the portfolio.

Project Structure

portfolio_app/
├── app.py                 # Dash app factory
├── config.py              # Pydantic settings
├── pages/
│   ├── home.py            # Bio landing (/)
│   ├── about.py           # About page
│   ├── contact.py         # Contact form
│   ├── projects.py        # Project showcase
│   ├── resume.py          # Resume/CV
│   ├── blog/              # Blog system
│   │   ├── index.py       # Article listing
│   │   └── article.py     # Article renderer
│   └── toronto/           # Toronto dashboard
│       ├── dashboard.py   # Main layout with tabs
│       ├── methodology.py # Data documentation
│       ├── tabs/          # Tab layouts (5)
│       └── callbacks/     # Interaction logic
├── components/            # Shared UI components
├── figures/               # Plotly figure factories
├── content/
│   └── blog/              # Markdown blog articles
├── toronto/               # Toronto data logic
│   ├── parsers/           # API data extraction
│   ├── loaders/           # Database operations
│   ├── schemas/           # Pydantic models
│   └── models/            # SQLAlchemy ORM
└── errors/                # Exception handling

dbt/
├── models/
│   ├── staging/           # 1:1 source tables
│   ├── intermediate/      # Business logic
│   └── marts/             # Analytical tables

notebooks/                 # Data documentation (15 notebooks)
├── overview/              # Overview tab visualizations
├── housing/               # Housing tab visualizations
├── safety/                # Safety tab visualizations
├── demographics/          # Demographics tab visualizations
└── amenities/             # Amenities tab visualizations

docs/
├── PROJECT_REFERENCE.md   # Architecture reference
├── CONTRIBUTING.md        # Developer guide
└── project-lessons-learned/

Tech Stack

Layer Technology
Database PostgreSQL 16 + PostGIS
Validation Pydantic 2.x
ORM SQLAlchemy 2.x
Transformation dbt-postgres
Data Processing Pandas, GeoPandas
Visualization Dash + Plotly
UI Components dash-mantine-components
Testing pytest
Python 3.11+

Development

make test      # Run pytest
make lint      # Run ruff linter
make format    # Format code
make ci        # Run all checks
make dbt-run   # Run dbt models
make dbt-test  # Run dbt tests

Environment Variables

Copy .env.example to .env and configure:

DATABASE_URL=postgresql://user:pass@localhost:5432/portfolio
POSTGRES_USER=portfolio
POSTGRES_PASSWORD=<secure>
POSTGRES_DB=portfolio
DASH_DEBUG=true
SECRET_KEY=<random>

Documentation

  • For developers: See docs/CONTRIBUTING.md for setup and contribution guidelines
  • For Claude Code: See CLAUDE.md for AI assistant context
  • Architecture: See docs/PROJECT_REFERENCE.md for technical details

License

MIT

Author

Leo Miranda

Description
Analytics portfolio: Toronto Housing Dashboard (choropleth visualization, multi-source ETL, geospatial analysis) + Energy Pricing Analysis (ML prediction). Built with Dash, PostgreSQL/PostGIS, dbt, and Pydantic.​​​​​​​​​​​​​​​​
Readme MIT 30 MiB
Languages
Python 82.6%
Jupyter Notebook 14.7%
Makefile 1.4%
Shell 0.7%
CSS 0.6%