{ "cells": [ { "cell_type": "markdown", "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "hidden": true }, "report_default": { "hidden": true } } } }, "tags": [ "remove_cell" ] }, "source": [ "# NYC Mobility Equity Dashboard\n", "This interactive dashboard analyzes whether **FHV** and **Yellow Taxi** services are over- or under-represented in areas with different demographic compositions relative to the NYC baseline.\n", "Select a month below to dynamically update all maps and tables." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "hidden": true }, "report_default": { "hidden": true } } } }, "tags": [ "remove_cell" ] }, "outputs": [], "source": [ "# Load data pipeline (Read-Only Mode)\n", "import duckdb\n", "from dashboard_helpers import build_trip_map, build_demo_map, build_stats\n", "\n", "# Connect to our pre-baked database in read-only mode to prevent file locks\n", "con = duckdb.connect('processed_dashboard.db', read_only=True)\n", "con.install_extension('spatial')\n", "con.load_extension('spatial')\n", "\n", "# Grab the baselines\n", "baseline_df = con.sql(\"SELECT * FROM city_baselines\").df()\n", "baseline_white = float(baseline_df[\"baseline_white_pct\"].iloc[0]) / 100.0\n", "baseline_black = float(baseline_df[\"baseline_black_pct\"].iloc[0]) / 100.0\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "hidden": true }, "report_default": { "hidden": true } } } }, "tags": [ "remove_cell" ] }, "outputs": [], "source": [ "# Widget setup\n", "import ipywidgets as widgets\n", "from IPython.display import display, clear_output\n", "\n", "month_slider = widgets.SelectionSlider(\n", " options=['Jan2025', 'Feb2025', 'Mar2025'],\n", " value='Feb2025',\n", " description='Select Month:',\n", " continuous_update=False,\n", " readout=True,\n", " style={'description_width': '120px'},\n", " layout=widgets.Layout(width='700px')\n", ")\n", "\n", "map_fhv_pu_out = widgets.Output()\n", "map_yellow_pu_out = widgets.Output()\n", "\n", "map_fhv_do_out = widgets.Output()\n", "map_yellow_do_out = widgets.Output()\n", "\n", "map_white_pct_out = widgets.Output()\n", "map_black_pct_out = widgets.Output()\n", "\n", "stats_fhv_pu_out = widgets.Output()\n", "stats_yellow_pu_out = widgets.Output()\n", "stats_fhv_do_out = widgets.Output()\n", "stats_yellow_do_out = widgets.Output()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "hidden": true }, "report_default": { "hidden": true } } } }, "tags": [ "remove_cell" ] }, "outputs": [], "source": [ "# Dashboard update logic\n", "def update_dashboard(change):\n", " month = month_slider.value\n", "\n", " with map_fhv_pu_out:\n", " clear_output(wait=True)\n", " display(build_trip_map(con, 'FHV', month, 'pu', 'Blues', 'FHV Pickups'))\n", " with map_yellow_pu_out:\n", " clear_output(wait=True)\n", " display(build_trip_map(con, 'Yellow', month, 'pu', 'Blues', 'Yellow Pickups'))\n", "\n", " with map_fhv_do_out:\n", " clear_output(wait=True)\n", " display(build_trip_map(con, 'FHV', month, 'do', 'Greens', 'FHV Drop-offs'))\n", " with map_yellow_do_out:\n", " clear_output(wait=True)\n", " display(build_trip_map(con, 'Yellow', month, 'do', 'Greens', 'Yellow Drop-offs'))\n", "\n", " with stats_fhv_pu_out:\n", " clear_output(wait=True)\n", " h, s = build_stats(con, 'FHV', month, 'pu', 'Blues', 'Pickups')\n", " display(h); display(s)\n", " with stats_yellow_pu_out:\n", " clear_output(wait=True)\n", " h, s = build_stats(con, 'Yellow', month, 'pu', 'YlOrBr', 'Pickups')\n", " display(h); display(s)\n", "\n", " with stats_fhv_do_out:\n", " clear_output(wait=True)\n", " h, s = build_stats(con, 'FHV', month, 'do', 'Greens', 'Drop-offs')\n", " display(h); display(s)\n", " with stats_yellow_do_out:\n", " clear_output(wait=True)\n", " h, s = build_stats(con, 'Yellow', month, 'do', 'YlOrBr', 'Drop-offs')\n", " display(h); display(s)\n", "\n", "\n", "def render_baseline_maps():\n", " with map_white_pct_out:\n", " clear_output(wait=True)\n", " display(build_demo_map(\n", " con, 'white_pct', baseline_white * 100,\n", " f'White Pop. Deviation from Baseline ({baseline_white*100:.1f}%)'))\n", " with map_black_pct_out:\n", " clear_output(wait=True)\n", " display(build_demo_map(\n", " con, 'black_pct', baseline_black * 100,\n", " f'Black Pop. Deviation from Baseline ({baseline_black*100:.1f}%)'))\n", "\n", "month_slider.observe(update_dashboard, names='value')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 0, "height": 2, "hidden": false, "row": 0, "width": 12 } } } } }, "outputs": [], "source": [ "# Title and Slider\n", "header_html = widgets.HTML(\"\"\"\n", "
\n", " This interactive dashboard analyzes whether FHV and Yellow Taxi services\n", " are over- or under-represented in areas with different demographic compositions\n", " relative to the NYC baseline.\n", "
\n", "\n", " Drag the slider below to change the month. All maps and tables update together.\n", "
\n", "