Week 5: Data Visualization Foundations
Quick overview of today’s plan:
groupby?Activity
Converse with your neighbor and identify…
Tell me, what are some insights you gather from this table:
| Month | Product A | Product B | Product C |
|---|---|---|---|
| Jan | 1050 | 1501 | 1200 |
| Feb | 987 | 1482 | 1093 |
| Mar | 1119 | 1428 | 1139 |
| Apr | 1129 | 1420 | 1081 |
| May | 1099 | 148 | 1018 |
| Jun | 1199 | 1396 | 1018 |
Tell me, what are some insights you gather from this plot:
Activity
You have 4 minutes.
Scenario 1
You’ve just pulled a messy dataset and need to quickly see if there are obvious data quality issues or trends before cleaning it.
Scenario 2
You’re presenting quarterly revenue trends to the CFO and CEO in a boardroom setting. The chart will appear in a formal report and on a slide.
Scenario 3
You’re building a tool for the marketing team that lets them interactively filter sales data by product category, store, and date range, and explore patterns themselves.
We should match how we visualize to the goal we have in mind.
We should match how we visualize to the goal we have in mind.
| Purpose | Example Tool | Example Use Case |
|---|---|---|
| Quick EDA | Pandas .plot() |
Checking missing data by month |
| Polished reporting | Matplotlib | Quarterly sales trends for execs |
| Interactive apps | Bokeh | Customer behavior dashboard |
Main Points:
Tip
Growing as a data scientist means growing your understanding of visualization as a whole.
This includes improving your ability to choose, design, and present visuals that best communicate your analytic findings for the specific task and audience at hand.
Pandas provides a .plot…
Pandas .plot() method is just a wrapper around Matplotlib
Pandas .plot() method is just a wrapper around Matplotlib
Tip
This provides us more refined control assuming we understand Matplotlib!
Tip
Use Matplotlib for Custom, Publication-Ready Visuals!
Start with the same data used in the Pandas section.
Gives you handles (fig, ax) for fine-grained control.
Add formatting, spacing, and readable ticks.
from matplotlib.ticker import StrMethodFormatter
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(
monthly['MoSold'], monthly['avg_sale_price'],
marker='o', linewidth=2
)
# Titles & labels
ax.set_title("Median Home Sale Price by Month", pad=10)
ax.set_xlabel("Month (1–12)")
ax.set_ylabel("Median Sale Price")
# Currency formatting with thousands separators
ax.yaxis.set_major_formatter(StrMethodFormatter('${x:,.0f}'))
# Tick improvements
ax.set_xticks(range(1,13))
ax.grid(True, alpha=0.3)
# Remove top/right spines for a cleaner look
for spine in ["top", "right"]:
ax.spines[spine].set_visible(False)
plt.tight_layout()
plt.show()Direct attention to the takeaway.
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(monthly['MoSold'], monthly['avg_sale_price'], marker='o', linewidth=2)
# Format
ax.yaxis.set_major_formatter(StrMethodFormatter('${x:,.0f}'))
ax.set_xticks(range(1,13))
ax.grid(True, alpha=0.3)
for spine in ["top","right"]:
ax.spines[spine].set_visible(False)
# Identify peak month
peak_idx = monthly['avg_sale_price'].idxmax()
peak_month = int(monthly.loc[peak_idx, 'MoSold'])
peak_value = float(monthly.loc[peak_idx, 'avg_sale_price'])
# Annotate the peak
ax.annotate(
f"Peak: {peak_month} (~{peak_value:,.0f})",
xy=(peak_month, peak_value),
xytext=(peak_month-3, peak_value),
arrowprops=dict(arrowstyle="->", lw=1.2),
fontsize=9
)
# Optional: reference line at annual median
ref = monthly['avg_sale_price'].median()
ax.axhline(ref, linestyle='--', linewidth=1, alpha=0.6)
ax.text(12.05, ref, f" Annual median ≈ ${ref:,.0f}", va='center')
ax.set_title("Median Home Sale Price by Month — Highlighting Peak & Annual Median", pad=10)
ax.set_xlabel("Month (1–12)")
ax.set_ylabel("Median Sale Price")
plt.tight_layout()
plt.show()Make it reproducible and ready for a report.
plt.rcParams.update({
"figure.dpi": 120,
"savefig.dpi": 300
})
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(monthly['MoSold'], monthly['avg_sale_price'], marker='o', linewidth=2)
ax.set_title("Median Home Sale Price by Month (Ames, IA)", pad=10)
ax.set_xlabel("Month (1–12)")
ax.set_ylabel("Median Sale Price")
ax.yaxis.set_major_formatter(StrMethodFormatter('${x:,.0f}'))
ax.set_xticks(range(1,13))
ax.grid(True, alpha=0.3)
for spine in ["top","right"]:
ax.spines[spine].set_visible(False)
plt.tight_layout()
plt.savefig("images/median_sale_price_by_month.png", bbox_inches="tight")
plt.show()alpha), smaller markers, or aggregate firstplt.style.use() once and for all plotsplt.tight_layout() or constrained_layout=TrueA Word of Caution on Matplotlib
Matplotlib is incredibly powerful, but it’s not always the most intuitive library—especially when you’re just getting started. Its API can feel verbose and a bit clunky compared to higher-level tools.
The good news? There’s a massive amount of example code out there, so if you can describe what you want, you can almost always find a solution by Googling or using your friendly AI copilot tool. Learning to adapt those examples to your needs is a valuable skill in itself.
Several Python libraries support interactivity:
Let’s create a nice plot showing the relationship between home sale price and living area — but interactive.
from bokeh.plotting import figure, show
from bokeh.models import HoverTool, ColumnDataSource, NumeralTickFormatter
from bokeh.transform import factor_cmap
from bokeh.io import output_notebook
# Render Bokeh plots inline (Jupyter/Colab)
output_notebook()
# If needed, load your data:
# df = pd.read_csv("../data/ames_clean.csv")[['GrLivArea','SalePrice','CentralAir']].dropna()
# ColumnDataSource
source = ColumnDataSource(df)
# Color map by CentralAir (adjust palette/order as desired)
palette = ['red', 'blue']
factors = list(df['CentralAir'].unique())
color_mapper = factor_cmap('CentralAir', palette=palette, factors=factors)
# Create the figure, stored in variable `p`
p = figure(
frame_width=700,
frame_height=350,
title='Relationship between home sale price and living area \nAmes, Iowa (2006-2010)',
x_axis_label='Living Area (Square feet)',
y_axis_label='Sale Price',
tools="pan,wheel_zoom,box_zoom,reset,save" # common interactive tools
)
# Scatter (with shared color mapping for fill & line)
p.scatter(
source=source,
x='GrLivArea',
y='SalePrice',
marker='circle',
alpha=0.25,
fill_color=color_mapper,
line_color=color_mapper,
legend_field='CentralAir'
)
# Legend & axis formatting
p.legend.title = "Has central air"
p.yaxis.formatter = NumeralTickFormatter(format="$,")
p.xaxis.formatter = NumeralTickFormatter(format=",")
# Hover tooltips
tooltips = [("Sale Price","@SalePrice{$0,0}"), ("SqFt","@GrLivArea{0,0}")]
hover = HoverTool(tooltips=tooltips, mode='mouse')
p.add_tools(hover)
# Show the plot inline
show(p)See more at: https://docs.bokeh.org/en/latest/docs/gallery.html
| Tool | Strengths | Best Use Cases |
|---|---|---|
| Pandas | Fast, tied to DataFrames, minimal setup | Quick EDA during analysis |
| Matplotlib | Complete control, high-quality output | Reports, presentations, publications |
| Bokeh | Interactive, web-friendly | Dashboards, stakeholder exploration, exploratory tools |
Scenario Recap:
You’re a data scientist at Regork, a national grocery chain.
You’ve been asked to identify a potential area of growth that could increase revenue or profits.
Deliverables:
Grading Criteria
We’ll discuss these in more depth in future classes:
Get Creative!
These are examples—you can explore your own ideas.
Example:
Example:
Dig Deeper
Bottom line: Provide a robust, multi-angle understanding of the business problem so you can paint a complete picture for the CEO.
Important
Don’t worry, we’ll continue to discuss the details & expectations of this mid-term over the next couple weeks.
Open floor for any questions regarding…
BANA 4080 | Week 5