{ "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", "

NYC Taxi Mobility Equity Dashboard

\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", "
\n", "\"\"\")\n", "\n", "annotated_slider = widgets.HBox(\n", " layout=widgets.Layout(justify_content='center', align_items='center', gap='10px')\n", ")\n", "\n", "display(header_html)\n", "display(annotated_slider)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 0, "height": 3, "hidden": false, "row": 2, "width": 6 } } } } }, "outputs": [], "source": [ "# FHV Pickup Map\n", "map_fhv_pu_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 6, "height": 3, "hidden": false, "row": 2, "width": 6 } } } } }, "outputs": [], "source": [ "# Yellow Pickup Map\n", "map_yellow_pu_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 0, "height": 3, "hidden": false, "row": 5, "width": 6 } } } } }, "outputs": [], "source": [ "# FHV Drop-off Map\n", "map_fhv_do_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 6, "height": 3, "hidden": false, "row": 5, "width": 6 } } } } }, "outputs": [], "source": [ "# Yellow Drop-off Map\n", "map_yellow_do_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 0, "height": 3, "hidden": false, "row": 8, "width": 6 } } } } }, "outputs": [], "source": [ "# White Population Baseline Map\n", "map_white_pct_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 6, "height": 3, "hidden": false, "row": 8, "width": 6 } } } } }, "outputs": [], "source": [ "# Black Population Baseline Map\n", "map_black_pct_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 0, "height": 3, "hidden": false, "row": 11, "width": 3 } } } } }, "outputs": [], "source": [ "# FHV Pickup Stats\n", "stats_fhv_pu_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 3, "height": 3, "hidden": false, "row": 11, "width": 3 } } } } }, "outputs": [], "source": [ "# Yellow Pickup Stats\n", "stats_yellow_pu_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 6, "height": 3, "hidden": false, "row": 11, "width": 3 } } } } }, "outputs": [], "source": [ "# FHV Drop-off Stats\n", "stats_fhv_do_out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "extensions": { "jupyter_dashboards": { "version": 1, "views": { "grid_default": { "col": 9, "height": 3, "hidden": false, "row": 11, "width": 3 } } } } }, "outputs": [], "source": [ "# Yellow Drop-off Stats\n", "stats_yellow_do_out" ] }, { "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": [ "# Trigger\n", "render_baseline_maps()\n", "update_dashboard(None)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbformat_minor": 5, "pygments_lexer": "ipython3", "version": "3.11.15" } }, "nbformat": 4, "nbformat_minor": 5 }