Welcome to Week 5

Three things today:

  1. Python Visualization — Pandas, Seaborn, Matplotlib, Bokeh in context
  2. EDA Framework — how to think through an analysis, not just run code
  3. The Semester Project — the scenario, deliverables, and lab preview

Four short exercises woven throughout — all pair discussions, no code required.

Discussion: Homework & Questions

Questions from Last Week?

  • Manipulating & cleaning DataFrames?
  • Aggregating data with groupby?
  • Joining datasets to bring in context?
  • Anything from the quiz or lab?

Activity

With your neighbor, identify:

  • 1 thing from last week that clicked and felt useful
  • 1 thing that is still fuzzy

Part 1: Python Visualization

Why Visualization Matters

Why We Visualize

  • Communicate insights quickly — a well-chosen chart reveals in seconds what a table hides in rows
  • Reveal patterns and outliers — shape, spread, and gaps are invisible in raw numbers
  • Support decision-making — stakeholders act on visuals, not on summary statistics alone
  • Expose data quality issues — unexpected spikes, missing ranges, and impossible values show up immediately in a plot

How Quickly Can You Spot Insights?

What can you tell from this table?

Week Produce Dairy Frozen Deli
1 11,500 12,100 7,320 4,100
2 12,800 11,400 7,180 4,080
3 12,200 10,800 1,780 4,120
4 13,900 10,100 7,410 4,090
5 13,400 9,800 7,260 4,110
6 15,100 9,200 7,350 4,085
7 14,800 8,700 7,420 4,115
8 16,400 8,100 7,190 4,095

How Quickly Can You Spot Insights?

What can you tell from this plot?

Different Visualization Needs

Scenario 1

You just pulled the Complete Journey data and need to quickly check whether basket spend looks reasonable before writing any analysis code.

Scenario 2

You’re presenting weekly revenue trends to the VP of Marketing in a board meeting. The chart will appear in a formal slide deck.

Scenario 3

The promotions team wants a tool to interactively explore coupon redemption rates by store, product category, and week.

Match the Tool to the Goal

We should match how we visualize to the goal we have in mind.


Purpose Tool Example Use Case
Quick EDA Pandas .plot() Spot-check basket spend distribution
Statistical comparison Seaborn Compare spend across income brackets
Polished reporting Matplotlib Weekly sales trend for an executive report
Interactive exploration Bokeh Let stakeholders filter by store or category

Pandas

Pandas for Quick EDA

  • First reach when you need a fast answer — minimal code, tied directly to DataFrames
  • Enough for exploratory work; not meant for final deliverables
  • When to use: speed over polish
# One-liner from aggregated data
basket_spend['basket_spend'].plot(kind='hist', bins=40, title='Basket Spend Distribution')

Tip

If you can answer your question in one line, Pandas .plot() is the right tool.

The .plot() Mental Model

One variable — call .plot() on a Series, specify kind:

series.plot(kind='hist')        # distribution of one column
series.plot(kind='box')         # spread and outliers
series.plot(kind='line')        # trend (index is x-axis)

Two variables — call .plot() on a DataFrame, add x= and y=:

df.plot(kind='scatter', x='col_a',    y='col_b')   # relationship
df.plot(kind='bar',     x='category', y='value') # comparison
df.plot(kind='line',    x='date',     y='value') # trend over time
df.plot(kind='barh',    x='category', y='value') # horizontal bars (long labels)

Tip

The kind= argument is the only required choice — everything else (figsize, title, xlabel, legend) is optional polish you layer on top.

Chart Types: Distribution

basket_spend['basket_spend'].plot(
    kind='hist', bins=40, figsize=(10, 3.2),
    title='Distribution of basket spend', xlabel='Basket spend ($)'
)
plt.tight_layout()
plt.show()

Chart Types: Category Comparison

category_totals.plot(
    kind='barh', x='department', y='sales_value',
    figsize=(10, 3.5), legend=False,
    title='Total revenue by department (top 10)', xlabel='Total sales ($)'
)
plt.tight_layout()
plt.show()

Chart Types: Trend Over Time

weekly_sales.plot(
    kind='line', x='week', y='total_sales',
    figsize=(10, 3.2), legend=False,
    title='Weekly total sales', ylabel='Total sales ($)'
)
plt.tight_layout()
plt.show()

Pandas is Just a Wrapper

Pandas .plot() calls Matplotlib under the hood — which means you can mix them:

plt.style.use('fivethirtyeight')

weekly_sales.plot(
    kind='line', x='week', y='total_sales',
    figsize=(10, 3), legend=False, title='Weekly total sales'
)
plt.tight_layout()
plt.show()

Tip

Knowing Matplotlib unlocks the full range of customization even when starting from a Pandas plot.

Exercise 1 — Try It 💻

Using the basket_spend DataFrame (already loaded):

Part A — One variable: Plot the distribution of basket_spend. Choose a kind that shows the shape of the data.

Part B — Two variables: basket_demo has both basket_spend and marital_status. Aggregate to get average basket spend per marital status, then plot a comparison.

4 minutes — write the code, run it, discuss what you see.

Seaborn

Seaborn for Statistical Visualization

  • Built on Matplotlib — cleaner syntax for common statistical chart types
  • Shines when you need: grouping, ordering, distributions with shape
  • One function call handles what Matplotlib needs 10–15 lines to produce


Pandas Seaborn
.plot(kind='hist') — basic bin counts histplot() — bins + KDE curve in one call
.groupby().mean().plot.bar() — manual aggregation barplot() / boxplot() — handles stats automatically
No built-in group ordering order= parameter on every chart

The Seaborn Mental Model

Every Seaborn function follows the same pattern:

sns.function(data=df, x='col', y='col', hue='group', ...)
Argument Role When to use
data= the DataFrame always
x= horizontal axis always
y= vertical axis two-variable plots
hue= color by group adds a third dimension
order= control category order ordered categoricals (income, size, day)

Common functions by goal:

sns.histplot(data=df, x='col', kde=True)                     # distribution shape
sns.boxplot(data=df, x='group', y='col', order=[…])          # spread across groups
sns.scatterplot(data=df, x='col_a', y='col_b', hue='group')  # relationship
sns.heatmap(pivot_df, cmap='YlOrRd')                         # matrix of values
sns.barplot(data=df, x='group', y='col', order=[…])          # mean + confidence interval

Distribution: histplot

fig, ax = plt.subplots(figsize=(10, 3.2))
sns.histplot(
    data=basket_demo,
    x='basket_spend',
    bins=50,
    kde=True,          # overlay a density curve
    ax=ax
)
ax.set_xlabel('Basket spend ($)')
ax.set_title('Distribution of basket spend — with density curve')
ax.set_xlim(0, 100)
plt.tight_layout()
plt.show()

Group Comparison: boxplot

fig, ax = plt.subplots(figsize=(10, 3.8))
sns.boxplot(
    data=basket_demo,
    x='income',
    y='basket_spend',
    order=income_order,   # explicit ordering — critical for income brackets
    ax=ax,
    showfliers=False
)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right', fontsize=8)
ax.set_xlabel('Income bracket')
ax.set_ylabel('Basket spend ($)')
ax.set_title('Basket spend by income bracket')
plt.tight_layout()
plt.show()

Patterns: heatmap

fig, ax = plt.subplots(figsize=(10, 3.8))
sns.heatmap(
    heatmap_data.iloc[:, 6:22],   # hours 6am–10pm
    cmap='YlOrRd',
    linewidths=0.3,
    ax=ax,
    cbar_kws={'label': 'Trip count'}
)
ax.set_xlabel('Hour of day')
ax.set_ylabel('')
ax.set_title('Shopping trips by day of week and hour')
plt.tight_layout()
plt.show()

When to Reach for Seaborn

Use Seaborn when you want to:

  • Compare distributions across groupshistplot, boxplot, violinplot
  • Visualize relationshipsscatterplot with hue, lmplot
  • Show patterns in a matrixheatmap
  • Do any of the above with ordered categorical variables

Tip

Seaborn handles the statistical aggregation and grouping for you. You still get a Matplotlib figure back — so you can use ax.set_title(), ax.set_xlabel(), etc. to polish it.

Exercise 2 — Seaborn Gallery Hunt 🔍

Browse the Seaborn example gallery for 3 minutes.

Find one plot that you think could reveal something interesting about the Complete Journey data.

Be ready to share:

  1. Which plot type you chose and what it’s called
  2. What CJ variables you’d put on each axis (or hue=)
  3. What pattern or insight you’d hope it reveals

3 minutes — browse, pick, discuss with your neighbor.

Matplotlib

Matplotlib for Full Control

  • The most widely used Python plotting library — and the foundation for Seaborn and Pandas
  • Full customization: labels, annotations, tick formatting, styles, multi-panel layouts, export
  • When to use: precision and polish for reports and presentations

Tip

Use Matplotlib when the chart needs to stand on its own — in a report, a slide deck, or a published figure.

The Figure / Axes Hierarchy

Everything in Matplotlib is an object you can reference and modify:

fig, ax = plt.subplots(figsize=(10, 2.5))
# fig = the overall canvas
# ax  = the actual plot area (axes, ticks, lines, labels)
fig.set_facecolor('#eaf4fb')
ax.set_facecolor('#d0eaf8')
ax.set_title('fig (blue border) contains ax (darker blue plot area)')
plt.tight_layout()
plt.show()

Step 0: Quick Pandas Starting Point

Start with a rough Pandas plot — fast, but no formatting:

weekly_sales.plot(kind='line', x='week', y='total_sales', figsize=(10, 3.0), legend=False)
plt.show()

Step 1: Move to the Figure / Axes API

Get handles — now you control everything:

fig, ax = plt.subplots(figsize=(10, 3.0))
ax.plot(weekly_sales['week'], weekly_sales['total_sales'], linewidth=2)
ax.set_title('Weekly total sales')
ax.set_xlabel('Week')
ax.set_ylabel('Total sales ($)')
plt.tight_layout()
plt.show()

Step 2: Executive-Ready Formatting

fig, ax = plt.subplots(figsize=(10, 3.2))
ax.plot(weekly_sales['week'], weekly_sales['total_sales'], linewidth=2)
ax.set_title('Weekly total sales — Regork grocery chain', pad=10)
ax.set_xlabel('Week')
ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('${x:,.0f}'))
ax.grid(True, alpha=0.3)
for spine in ['top', 'right']:
    ax.spines[spine].set_visible(False)
plt.tight_layout()
plt.show()

Step 3: Highlight the Insight

fig, ax = plt.subplots(figsize=(10, 3.5))
ax.plot(weekly_sales['week'], weekly_sales['total_sales'], linewidth=2)
ax.set_title('Weekly total sales — note holiday spike in late December', pad=10)
ax.set_xlabel('Week')
ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('${x:,.0f}'))
ax.grid(True, alpha=0.3)
for spine in ['top', 'right']:
    ax.spines[spine].set_visible(False)

peak_idx = weekly_sales['total_sales'].idxmax()
peak_week = weekly_sales.loc[peak_idx, 'week']
peak_val  = weekly_sales.loc[peak_idx, 'total_sales']

ax.annotate(
    f'Holiday spike\n${peak_val:,.0f}',
    xy=(peak_week, peak_val),
    xytext=(peak_week - pd.Timedelta(weeks=8), peak_val * 0.97),
    arrowprops=dict(arrowstyle='->', lw=1.2),
    fontsize=9
)
plt.tight_layout()
plt.show()

Step 3: Highlight the Insight

Matplotlib Is the Foundation

Most Python visualization libraries are built on top of Matplotlib — so once you know the Figure/Axes API, you can refine plots from Seaborn, Pandas, and others using the exact same code.

# --- Seaborn draws the plot ---
fig, ax = plt.subplots(figsize=(10, 3.8))
sns.boxplot(
    data=basket_demo, x='income', y='basket_spend',
    order=income_order, ax=ax, showfliers=False,
    color='steelblue'
)

# --- Matplotlib polishes it ---
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right', fontsize=8)
ax.set_xlabel('Income bracket')
ax.set_ylabel('Basket spend ($)')
ax.set_title('Basket spend by income — same Seaborn call, Matplotlib finishing touches')
ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('${x:,.0f}'))
for spine in ['top', 'right']:
    ax.spines[spine].set_visible(False)
plt.tight_layout()
plt.show()

Matplotlib Is the Foundation

Common Gotchas

Problem Fix
Unreadable axis numbers StrMethodFormatter('${x:,.0f}') for currency
Cluttered or overlapping labels rotation=45, ha='right' on tick labels
Overplotting alpha=0.3 on scatter points
Cramped layout plt.tight_layout() or constrained_layout=True
Inconsistent styles plt.style.use() once at the top of your notebook

A Note on Matplotlib’s Learning Curve

Matplotlib is powerful but verbose. The good news: there is a massive example gallery and AI tools are very good at helping adapt Matplotlib code. Learning to describe what you want and adapt examples is itself a valuable skill.

Exercise 3 — Matplotlib Gallery Hunt 🔍

Browse the Matplotlib example gallery for 3 minutes.

Find one plot that you think could reveal something interesting about the Complete Journey data.

Be ready to share:

  1. Which plot type you chose and what it’s called
  2. What CJ variables you’d use and how
  3. What pattern or insight you’d hope it reveals

3 minutes — browse, pick, discuss with your neighbor.

Bokeh

Bokeh for Interactive Visualization

  • Renders HTML/JavaScript — charts live in a browser, not just a notebook
  • Users can zoom, pan, hover, and filter without writing new code
  • Best for: dashboards, stakeholder exploration tools, final deliverables that need to be shared
Loading BokehJS ...

Interactive Weekly Sales Explorer

source = ColumnDataSource(weekly_sales)

p = figure(
    title='Total Weekly Sales — hover, zoom, and pan to explore',
    x_axis_type='datetime',
    width=750, height=350,
    tools='pan,wheel_zoom,box_zoom,reset,save'
)

p.line('week', 'total_sales', source=source,
       line_width=2, color='steelblue')

hover = HoverTool(tooltips=[
    ('Week',  '@week{%F}'),
    ('Sales', '@total_sales{$0,0}')
], formatters={'@week': 'datetime'})
p.add_tools(hover)

p.xaxis.axis_label = 'Week'
p.yaxis.axis_label = 'Total Sales ($)'

show(p)

Tip

Run this in the companion notebook to see the interactive version — it won’t fully render in a static slide.

Which Tool When?


Tool Strengths Best For
Pandas Fast, one-liner, tied to DataFrames Quick spot-checks during EDA
Seaborn Statistical grouping, ordering, distributions Comparing groups, showing spread
Matplotlib Complete control, publication quality Reports, presentations, polished figures
Bokeh Interactive, web-ready, shareable HTML Dashboards, stakeholder exploration

Part 2: How to Think About EDA

EDA Is a Conversation With Your Data

Exploratory Data Analysis is not a checklist of charts to run.

It is a sequence of questions — each answer raising the next question.

Data dump (avoid)

  • Plot every variable
  • Report every mean and median
  • Move on

Real EDA (aim for)

  • Start with a sharp question
  • Let findings drive the next step
  • Stop when you can tell a story

Important

The goal is not to show that you looked at the data. The goal is to find something worth saying.

A Framework for EDA

flowchart LR
    A["1️⃣ Question"] --> B["2️⃣ Structure"]
    B --> C["3️⃣ Distributions"]
    C --> D["4️⃣ Segmentation"]
    D --> E["5️⃣ Story"]
    style A fill:#2c3e50,color:#fff
    style B fill:#2980b9,color:#fff
    style C fill:#27ae60,color:#fff
    style D fill:#e67e22,color:#fff
    style E fill:#8e44ad,color:#fff


Step Question to ask
Question What do I actually want to know? Is it specific enough to know when I’ve answered it?
Structure What shape is the data? What do I need to join? Where are the missings?
Distributions What does the outcome variable look like across all households? Any outliers?
Segmentation Does the pattern differ across groups? Where does the interesting variation live?
Story What changed? What surprised me? What should the decision-maker do next?

Step 1: Start With a Sharp Question

The question determines everything that follows.

Caution

Too broad: “How do customers shop?”

This can’t be answered — no unit of analysis, no metric, no comparison to make.

Tip

Sharp: “Do households that redeem coupons have larger basket spend than those that don’t — and does this differ across income brackets?”

This names: the unit (basket), the metric (spend), the comparison (coupon vs. no coupon), and the segmentation (income).

A sharp question tells you exactly which tables to join, which columns to compute, and what a result would look like.

Steps 2–3: Structure → Distributions

Check your data before trusting it:

# Step 2: understand the shape
print(f"Baskets: {basket_spend['basket_id'].nunique():,}")
print(f"Households with demographics: {basket_demo['household_id'].nunique():,}")
print(f"Median basket spend: ${basket_demo['basket_spend'].median():.2f}")
Baskets: 155,848
Households with demographics: 801
Median basket spend: $19.91

Step 4: Segmentation — Where the Story Lives

Distributions tell you what. Segmentation tells you who and where.

The segmentation raised a new question: Why does it flatten? Is it basket size (fewer items) or price per item?

Step 5: Build the Story

A good EDA concludes with something worth saying:

  • What did you find that you did not expect?
  • What would you recommend based on this finding?
  • What would you investigate next?

The “So What” Test

After every chart, ask: So what? If you can’t answer that in one sentence — why a decision-maker should care — the chart is not yet doing its job.

A data dump shows charts. A good EDA tells a story.

Before Thursday: Read Chapter 15

Thursday’s lab is the project ideation session — you’ll brainstorm and pitch.

To get the most out of it, read Chapter 15 (EDA) before lab.

It walks through a full EDA case study on the Complete Journey data and shows the framework in action from first question to final story. Coming in with that mental model will make Thursday’s brainstorming sharper.

Tip

The companion notebook for Chapter 15 is runnable in Colab — follow along and experiment with your own questions as you read.

Exercise 4 — What’s the Next Question? 🤔

A teammate reports this finding:

“Households in the top two income brackets spend 38% more per basket on average than households in the bottom two brackets.”

Name 3 follow-up questions you would investigate next and explain what each one would reveal.

Discuss with your neighbor for 3 minutes.

Part 3: The Semester Project

The Regork Scenario

You are a data scientist at Regork, a national grocery chain.

Your manager has asked you to identify a potential growth opportunity — an area where the company could invest future resources to increase revenue or profits.

Your task:

  1. Define a clear business question that investigates a specific growth opportunity
  2. Analyze the Complete Journey data to answer it
  3. Communicate your findings through:
    • A written analytic report (Jupyter Notebook → HTML)
    • A 3-minute recorded presentation for the CEO

Tip

Groups: 2–4 students. Sign up in Canvas → People → Project Groups.

What a Sharp Business Question Looks Like

Caution

Too vague

“We want to understand how customers shop.”

No unit of analysis. No metric. No comparison. Cannot be answered.

Caution

Better, but still broad

“Do different income groups shop differently?”

“Differently” could mean anything — frequency, basket size, category mix, price sensitivity.

Tip

Sharp

“Do households in the bottom two income brackets redeem coupons at higher rates — and does redemption translate into larger basket spend, or just a cheaper version of the same basket?”

Has a unit (basket), a metric (spend), a comparison (redemption vs. not), and a segmentation (income). You would know when you had answered it.

What Strong Analysis Looks Like

Clear business problem — state one specific, answerable question tied to a real decision. Not “understand customer behavior.” Something like: “Do low-income households redeem coupons at higher rates, and does redemption translate into larger basket spend or just a cheaper version of the same basket?”

Proposed value to the decision-maker — name who acts on your findings and what they would do differently. The VP of Promotions needs a recommendation, not a summary of what you computed.

Logical, methodical analysis — start with data structure and distributions, then move into group comparisons and segmentation. Each step should raise the next question. Show your reasoning, not just your outputs.

Clearly explained findings — every chart and table earns its place by making one point. Label axes properly, use readable scales, and narrate what the reader should see. Plots without interpretation are just decoration.

Polished communication — the report reads as a coherent story, not a list of code cells. The presentation looks like a business deck, not a notebook printout. Your audience is an executive, not a grader.

Clear recommendations — end with something actionable. “Based on our findings, we recommend…” is a sentence your report and presentation must contain.

Deliverables

A. Written Technical Report

  • Jupyter Notebook rendered to HTML
  • Must include: data preparation, business question, EDA, narrative findings, recommendations
  • Show relevant code; suppress warnings and distracting output
  • File naming: YYYY_BANA7025_groupXX_project.html

B. Recorded Stakeholder Presentation

  • 3 minutes maximum — no code, executive audience
  • Covers: business problem, key findings, one clear recommendation
  • Recorded via Zoom or Kaltura and submitted through Canvas

Note

One group member submits both deliverables together. Submit early — large video files can take time to upload.

Before You Start — Read the Project Details

Go to Canvas → Assignments → Project

The Canvas project page has everything you need before writing a single line of code:

  • Full project description — the Regork scenario, what counts as a strong business question, and how to structure your analysis
  • Complete grading rubric — the exact criteria and point values for both the report and the presentation
  • Example submissions — real reports and presentations from a previous course. Study what makes them strong before you start.

Reading the rubric before you start is one of the highest-leverage things you can do.

What Gets Graded

75 points total — split across a written report (40 pts) and a recorded presentation (35 pts).


Report (40 pts)

Section Pts What We’re Looking For
Introduction 5 Clear business problem, approach, and proposed value to the decision-maker
Packages 5 All imports upfront, warnings suppressed, unfamiliar libraries explained
EDA 10 Non-obvious insights, polished plots + tables, findings clearly narrated
Summary 5 Problem, approach, insights, recommendations, and limitations
Code & Craft 15 Clean style, systematic logic, mastery — notebook runs without errors


Presentation (35 pts)

Section Pts What We’re Looking For
Introduction 5 Business problem, approach, and proposed solution — no code
Findings 10 Key charts and tables, one point per visual, clearly explained
Summary 5 Insights, implications, clear recommendation, and limitations
Delivery 15 ≤ 3 minutes, professional, compelling narrative — executive audience

Tip

The EDA section (10 pts) is where most projects separate. Uncovering a non-obvious pattern and explaining why it matters is worth more than five polished charts that say nothing new.

Thursday’s Lab: Project Ideation

In Thursday’s lab you will:

  1. Form your group (2–4 students) and join a Canvas group
  2. Brainstorm three distinct project ideas, each with a business problem, decision-maker, data plan, and success criteria
  3. Choose your most compelling idea and do a 2–3 minute stand-up pitch to the class

Tips for a Strong Pitch

  • Lead with the question, not the dataset
  • Name a specific decision-maker and what they would do with your findings
  • Describe what a meaningful finding would look like — not just “explore the data”

After lab: refine your idea into a formal proposal (the homework due this week).

Key Takeaways

Part 1 — Python Visualization

  • Match the tool to the goal: Pandas for speed, Seaborn for statistical grouping, Matplotlib for polish, Bokeh for interactivity
  • Pandas is a wrapper over Matplotlib — knowing both gives you full control

Part 2 — EDA Framework

  • EDA is a conversation: question → structure → distributions → segmentation → story
  • The “so what” test: if you can’t explain why a chart matters to a decision-maker, it’s not done yet

Part 3 — The Project

  • A sharp business question is the foundation — everything else follows from it
  • Read Chapter 15 before Thursday’s lab
  • Lab: pitch your idea; Homework: formal proposal

Q&A 🙋

Open floor for questions on:

  • Today’s visualization topics or exercises
  • The EDA framework and how it connects to the project
  • Project scope, deliverables, or proposal sections
  • Anything from the reading or labs so far