👥 Data Visualization · Python · d3blocks

Life in Motion

Visualizing how Vietnamese people spend their time using moving bubble charts

🗂 Dataset: diary_main.csv 🫧 Moving Bubbles (d3blocks) 🎨 Color map: HSV 🇻🇳 Vietnamese Time-Use Survey
Visualization
Moving
Bubble Chart
Library
d3blocks
+ Pandas
Center State
Travel
Pivot activity
Output
.html
Interactive file

This project uses d3blocks' moving bubbles to animate how individual respondents from a Vietnamese time-use survey transition between daily activities over time. Each bubble represents a person; its position reflects their current activity state, creating an organic, living visualization of collective behavior.

📂
Upload CSV
google.colab
files.upload()
🕐
Convert Time
minutes → datetime
strftime / gmtime
🏷️
Map Activities
activity codes →
readable labels
Reduce Size
iloc[:len/4]
faster rendering
🫧
Render Chart
d3.movingbubbles
→ .html export

Raw survey data uses numeric codes (e.g. Q401 = 1501) to represent activities. A custom get_activity() function translates 50+ codes into 15 human-readable categories, applied at read time via Pandas converters.

💼
Work
101–502
🚌
Travelling
198, 298…
🛒
Shopping
602
🏠
Housework
601
👶
Caring
701, 702
📚
Education
901–903
🎭
Entertainment
1201–1299
Sport
1301–1399
📺
TV / Youtube
1402
🌐
Surf Web
1404
😴
Sleeping
1501
🍜
Eating
1502
🚿
Personal Hygiene
1503
😌
Relaxing
1506
🍱
Sell Food
501
💇
Provide Services
504–508
time_converter.py — minutes → datetime
def convert_time(minute):
    # Converts minutes since epoch to formatted datetime string
    return strftime("%Y-%m-%d %H:%M:%S", gmtime(int(minute) * 60))
load_data.py — read & transform on import
data = pd.read_csv("4_diary_main.csv",
                  usecols=[ "ID", "BEGIN", "Q401" ],
                  encoding='latin-1',
                  converters={
                      "Q401": get_activity,
                      "BEGIN": convert_time
                  })

# Sort + rename for d3blocks expected schema
data = data.sort_values(["ID", "BEGIN"])
data = data.rename(columns={"ID": "sample_id", "BEGIN": "datatime", "Q401": "state"})
data = data.iloc[:int(len(data) / 4)]  # reduce for performance
render.py — d3blocks moving bubbles
d3 = D3Blocks()

d3.movingbubbles(
    data,
    datetime="datatime",
    sample_id="sample_id",
    state="state",
    filepath="./moving_point.html",
    note="How Vietnamese people spend their time",
    cmap="hsv",
    center="Travelling",  # pivot activity
    size=2,
    figsize=(780, 900),
    dt_format="%Y-%m-%d %H:%M:%S"
)
🫧

moving_point.html — Interactive Bubble Animation

A self-contained HTML file with embedded D3.js. Each bubble = one respondent. Bubbles drift between activity clusters as time advances, revealing patterns in daily Vietnamese life.

780 × 900 px canvas HSV color map Center: Travelling Self-contained .html Exported via Colab

Watch the demo on YouTube to see the animation in action — bubbles transition fluidly between Sleeping, Working, Eating, Travelling and more across the full survey day.

🎯
Center = Travelling
Travelling is used as the pivot/center state — it acts as a natural transition hub between most other daily activities, making transitions visually smooth and legible.
Performance Trade-off
Data is reduced to 25% of its original size (iloc[:len/4]) to ensure the browser can render the animation without lag in Google Colab.
🕐
Time Conversion
Raw survey timestamps are stored as minutes since epoch. A custom converter transforms them into ISO datetime strings at read time — no post-processing needed.
🏷️
Converter at Read Time
Both get_activity() and convert_time() are passed as Pandas converters, keeping the transformation pipeline clean and inline.
🎨
HSV Color Map
The HSV colormap assigns visually distinct, saturated colors to each of the 16 activity categories, making state transitions immediately recognizable at a glance.
📤
Portable Output
The output is a single self-contained .html file with D3.js embedded — shareable anywhere without a server, database, or Python runtime.
🇻🇳

Bringing survey data to life

By combining Pandas' converter pipeline with d3blocks' moving bubble chart, this project transforms a flat time-use survey CSV into a living, breathing animation. Viewers can observe collective rhythms — when people sleep, eat, work, and travel — in a single, shareable interactive file. A demonstration that data visualization can be both technically rigorous and genuinely engaging.