# Streaming Services — Customer Survey 2026
A self-contained Vizro dashboard surfacing customer-survey insights for
seven major streaming services (Netflix, Disney+, HBO Max, Prime Video,
Apple TV+, Paramount+, Crunchyroll). Two interactive tabs, ten global
filters, a green & yellow visual identity.
> **Note on data.** The respondent-level CSV in `data/` is fully
> synthetic — generated deterministically by `scripts/build_mock_data.py`
> with a fixed seed. The dashboard is intended as a demonstration /
> design preview, not a real research artefact. Replace the CSV with
> your own respondent-level data (matching the schema in
> `aggregators.py`) to point it at real numbers.
## Run locally
```bash
# 1) Generate the synthetic respondent dataset (only needed once;
# the CSV + JSON outputs are committed alongside the source).
/path/to/venv/bin/python MockupDashboard/scripts/build_mock_data.py
# 2) Boot the live Vizro app (port 8072 by default; override with PORT=…).
/path/to/venv/bin/python MockupDashboard/app.py
```
Then open http://127.0.0.1:8072/ in a browser.
## Deploy to py.cafe
py.cafe runs Vizro apps natively. To deploy:
1. Open <https://py.cafe/> and create a new project, choosing the
**Vizro** template.
2. In the side panel, upload **every file in this folder** preserving
the relative structure (`app.py` at the project root, plus the
`dashboard/`, `data/`, `assets/` subfolders, plus `theme.py`,
`aggregators.py` and `requirements.txt`). The simplest way is to
drag-and-drop this folder's contents straight into py.cafe's file
tree.
3. Make sure the entry file is set to `app.py`.
4. Save / Run — py.cafe installs `requirements.txt` and boots the app.
`app.py` already detects py.cafe (or any environment that exposes a
`PORT` env var) and switches to deploy mode automatically: binds to
`0.0.0.0`, disables Flask debug, disables the reloader. It also exposes
a WSGI `server` handle, so any standard PaaS (Heroku, Railway, Fly,
Render, etc.) can run it via `gunicorn app:server`.
### What to upload
Required:
```
app.py
requirements.txt
theme.py
aggregators.py
dashboard/__init__.py
dashboard/wording.py
dashboard/chart_layout.py
dashboard/chart_logic.py
dashboard/layout.py
data/respondent_level.csv
data/filter_options.json
assets/_shell.css
assets/_charts.css
assets/_menu.js
```
Optional / not needed at runtime:
```
scripts/build_mock_data.py # only needed if you regenerate data
README.md
```
### File-size note
`data/respondent_level.csv` is ~503 KB (2,000 rows × 71 columns). All
other files are < 50 KB. Total project size is well under typical
py.cafe per-file and per-project limits.
## Tabs
- **1. Drivers of streaming choice** — heatmap of reasons × services
with a weighted-base bubble row above each column. Three sub-tabs:
- A. Why subscribers picked their primary service over their
previous one (positive / green ramp)
- B. Why subscribers' primary service is the best fit for them
(positive / green ramp)
- C. Why respondents would not subscribe to a service
(negative / yellow → amber ramp)
- **2. Overall satisfaction by streaming service** — per-service stacked
distribution bars (5 buckets: Not at all → Very satisfied) with N and
weighted-average bubbles per row.
## Data schema
- 7 streaming services: Netflix, Disney+, HBO Max, Prime Video, Apple
TV+, Paramount+, Crunchyroll.
- 2,000 synthetic respondents (deterministic, seed = 42).
- 10 global filter columns: gender, generation, country, income,
monthly streaming spend, primary device, household type, employment,
education, habitat.
To regenerate the dataset (e.g. change service-share weights or sample
size), edit `scripts/build_mock_data.py` and rerun it. The seed is
fixed so the data is reproducible.
## Project layout
```
MockupDashboard/
app.py # Vizro entry point (run locally + on py.cafe)
requirements.txt # vizro / dash / plotly / pandas / numpy
theme.py # Plotly green/yellow template + apply_theme()
aggregators.py # Respondent-level → tab-shaped aggregates
dashboard/
__init__.py
wording.py # Every visible string + service & reason labels
chart_layout.py # Margins, legend SVGs, swatch helpers, colour cells
chart_logic.py # Tab 1 heatmap + Tab 2 stacked-bar figure builders
layout.py # Vizro page tree + 10 filters + @capture wrappers
data/
respondent_level.csv # 2,000 synthetic rows × 71 cols
filter_options.json # Ordered options for each filter dropdown
assets/
_shell.css # Banner + sidebar + hamburger drawer
_charts.css # Chart container polish
_menu.js # Hamburger drawer behaviour
scripts/
build_mock_data.py # Deterministic synthetic-data generator
README.md
```