matplotlib seaborn projects part 2
No account is required. Learn the material, try the examples, and mark it complete when you are ready to move on. Sign in with email only if you want to save progress across devices.
Matplotlib & Seaborn Projects
Phase 1 → Thinking Like a Programmer → Exploratory Data Analysis
Welcome to the Matplotlib & Seaborn Projects notebook.
This notebook is a project-based continuation of the Exploratory Data Analysis phase. Instead of learning plotting functions in isolation, you will use visualization to investigate real analytical questions.
The goal is not:
"Can I make a chart?"
The goal is:
"Can I choose, construct, interpret, and communicate a chart that helps answer a question?"
You will work through several progressively harder projects covering:
- Matplotlib fundamentals
- Seaborn fundamentals
- categorical analysis
- distributions
- relationships between variables
- correlation
- time-series visualization
- subgroups and segmentation
- outlier investigation
- multi-variable visualization
- dashboard-style EDA
- storytelling with data
- responsible interpretation
Learning objectives
By the end of this notebook, you should be able to:
- Create publication-quality visualizations with Matplotlib.
- Use Seaborn for statistical exploratory visualizations.
- Select an appropriate chart for an analytical question.
- Explain what a visualization shows without overclaiming.
- Compare numerical distributions across categories.
- Investigate relationships between numerical variables.
- Visualize correlations.
- Analyze trends over time.
- Detect and investigate outliers visually.
- Use color, size, position, and faceting deliberately.
- Build a coherent EDA visualization workflow.
- Communicate findings in Markdown rather than relying on charts alone.
Core principle
A visualization is an analytical tool, not decoration.
For every chart in this notebook, answer:
- What question am I asking?
- Why is this chart appropriate?
- What pattern do I observe?
- What does that pattern potentially mean?
- What can I not conclude from this chart?
- What would I investigate next?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Reproducibility
RANDOM_STATE = 42
rng = np.random.default_rng(RANDOM_STATE)
# General plotting defaults
sns.set_theme(style="whitegrid", context="notebook")
print("NumPy:", np.__version__)
print("Pandas:", pd.__version__)
print("Seaborn:", sns.__version__)
NumPy: 1.26.4
Pandas: 2.1.4
Seaborn: 0.13.2
Part 1 - Visualization Foundations
Before beginning the projects, establish a mental model for visualization.
The visual encoding hierarchy
Different visual properties communicate information with different levels of precision.
Generally, viewers are better at comparing:
- position on a common scale
- position on different scales
- length
- angle
- area
- color intensity
- shape
This is one reason why a carefully designed bar chart is often easier to interpret than a pie chart.
Chart selection cheat sheet
| Analytical question | Recommended chart |
|---|---|
| How does a variable change over time? | Line chart |
| How large is each category? | Bar chart |
| What does a numerical variable look like? | Histogram |
| Are there potential outliers? | Box plot |
| How are two numerical variables related? | Scatter plot |
| How do distributions differ across groups? | Box/violin plot |
| How common is each category? | Count plot |
| How do many numerical variables relate? | Correlation heatmap |
| How does a relationship differ across groups? | Faceted scatter plots |
| What is the distribution shape? | Histogram/KDE |
Project 1 - Your First Analytical Chart
Scenario
You are a junior data analyst at an e-commerce company.
The product team asks:
Which products generate the most revenue?
Create a chart that answers the question clearly.
We will start with a small synthetic dataset so that the analytical logic is easy to understand.
products = pd.DataFrame({
"product": [
"Laptop", "Phone", "Tablet", "Monitor",
"Keyboard", "Mouse", "Headphones", "Webcam"
],
"revenue": [
185000, 240000, 112000, 97000,
42000, 28000, 76000, 51000
]
})
products
product revenue
0 Laptop 185000
1 Phone 240000
2 Tablet 112000
3 Monitor 97000
4 Keyboard 42000
5 Mouse 28000
6 Headphones 76000
7 Webcam 51000Task 1.1 - Create a basic bar chart
Requirements:
- use Matplotlib
- put products on the x-axis
- put revenue on the y-axis
- add a descriptive title
- label both axes
- make the chart readable
- call
plt.tight_layout()
Questions
Before running your code, decide:
- Should the bars be sorted?
- Should the y-axis have a currency label?
- Is the product order meaningful?
# TODO:
# 1. Sort the data by revenue.
# 2. Create a bar chart.
# 3. Add a title and axis labels.
# 4. Improve readability.
# 5. Display the chart.
# Example structure:
# sorted_products = products.sort_values("revenue", ascending=False)
#
# plt.figure(figsize=(10, 6))
# plt.bar(sorted_products["product"], sorted_products["revenue"])
# plt.title("Revenue by Product")
# plt.xlabel("Product")
# plt.ylabel("Revenue")
# plt.xticks(rotation=45)
# plt.tight_layout()
# plt.show()
Reflection
Write a short Markdown response:
- Which product generated the most revenue?
- Which generated the least?
- Is the difference between the top and bottom products substantial?
- What business question would you investigate next?
Remember: the chart establishes an observed pattern. It does not tell you why one product generated more revenue.
Project 2 - Sorting Makes Comparisons Easier
A chart can contain correct data and still be difficult to read.
Consider what happens when categories are presented in arbitrary order.
Your goal is to create a ranked bar chart.
Requirements
- Sort products from highest revenue to lowest revenue.
- Create a horizontal bar chart using
plt.barh(). - Put the highest-revenue product at the top.
- Format the chart so that the labels are easy to read.
- Add an informative title.
Why horizontal?
Product names can be long. Horizontal bars give category labels more room.
# TODO: Create a sorted horizontal bar chart.
# Hint:
# sorted_products = products.sort_values("revenue", ascending=True)
# Your code here
Reflection
Explain why the horizontal version is easier or harder to interpret.
Then answer:
What visual design decision had the biggest impact on readability?
Project 3 - Understanding Distributions
A single average can hide a great deal of information.
Suppose the business reports:
"The average order value is ₹4,800."
That sounds useful, but it does not tell us whether most orders are around ₹4,800 or whether a small number of very large orders pull the average upward.
We need a distribution.
Dataset
Generate synthetic order values with a realistic right-skewed distribution.
orders = pd.DataFrame({
"order_value": rng.lognormal(
mean=np.log(2500),
sigma=0.75,
size=3000
)
})
orders["order_value"].describe()
count 3000.000000
mean 3254.509063
std 2786.769355
min 162.022691
25% 1485.369164
50% 2499.551329
75% 4025.685598
max 27124.326753
Name: order_value, dtype: float64Task 3.1 - Histogram
Create a histogram showing the distribution of order values.
Requirements:
- use Matplotlib
- experiment with different numbers of bins
- label the axes
- include units
- give the chart a meaningful title
Try at least:
- 10 bins
- 30 bins
- 60 bins
Then decide which communicates the distribution best.
# TODO: Create and compare histograms with different bin counts.
# Your code here
Task 3.2 - Mean vs median
Calculate:
- mean order value
- median order value
- standard deviation
- 90th percentile
- 99th percentile
Then explain why the mean and median differ.
Use:
orders["order_value"].mean()
orders["order_value"].median()
orders["order_value"].std()
orders["order_value"].quantile(0.90)
orders["order_value"].quantile(0.99)# TODO: Calculate summary statistics.
# Your code here
Task 3.3 - Add a KDE
Use Seaborn's histplot() with kde=True.
Then answer:
- What does the KDE add?
- Does it make the distribution easier or harder to interpret?
- When might a KDE be misleading?
Remember:
A KDE is an estimate of a distribution, not a collection of observed values.
# TODO: Create a Seaborn histogram with KDE.
# Your code here
Project 4 - Outlier Investigation
Outliers are not automatically mistakes.
They can represent:
- genuine high-value customers
- unusual events
- fraud
- measurement errors
- data-entry errors
- rare but important observations
Your job is to investigate rather than automatically delete.
Task 4.1 - Box plot
Create a horizontal box plot of order_value.
# TODO: Create a box plot for order_value.
# Your code here
Task 4.2 - Identify extreme orders
Use a quantile-based rule to identify unusually high-value orders.
One simple approach is to inspect the 99th percentile.
Then compare:
- number of orders above the 99th percentile
- percentage of all orders
- total revenue contributed by those orders
Important
This is an investigation threshold, not a universal definition of an error.
# TODO:
# 1. Calculate the 99th percentile.
# 2. Filter orders above it.
# 3. Count them.
# 4. Calculate their share of total order value.
# Your code here
Reflection
Write:
"The extreme orders account for approximately _% of transactions but _% of total order value."
Then explain what this means for the business.
Would it be appropriate to report only the mean order value? Why or why not?
Project 5 - Relationships Between Variables
Now move from one variable to two.
The business asks:
Do customers with higher incomes tend to spend more?
A scatter plot is an appropriate starting point.
Dataset
Generate a synthetic customer dataset.
n_customers = 1200
customers = pd.DataFrame({
"age": rng.integers(18, 70, size=n_customers),
"income": rng.lognormal(
mean=np.log(70000),
sigma=0.55,
size=n_customers
)
})
# Add a noisy relationship between income and annual spending
customers["annual_spending"] = (
customers["income"] * rng.normal(0.08, 0.025, size=n_customers)
+ rng.normal(0, 4500, size=n_customers)
)
customers["annual_spending"] = customers["annual_spending"].clip(lower=100)
customers.head()
age income annual_spending
0 45 39864.610408 1148.516053
1 68 78277.409984 4119.021783
2 21 45091.044628 6654.962818
3 60 51813.080961 2664.176676
4 46 68116.574803 100.000000Task 5.1 - Scatter plot
Create a scatter plot with:
- income on x
- annual spending on y
- informative labels
- an informative title
- reasonable figure size
Use Seaborn.
# TODO: Create the scatter plot.
# Your code here
Task 5.2 - Correlation
Calculate the Pearson correlation between income and annual spending.
Then answer:
- Is the relationship positive or negative?
- Is it weak, moderate, or strong?
- Does correlation prove that income causes spending?
- What other variables might matter?
# TODO: Calculate the correlation.
# Your code here
Important lesson: correlation is not causation
A scatter plot can reveal association.
It cannot, by itself, establish:
- causality
- direction of causality
- absence of confounding variables
- whether the relationship generalizes beyond this dataset
Good analysts separate:
What the data shows
from:
What they think might explain it.
Project 6 - Add a Third Variable
Suppose the relationship between income and spending differs by age group.
Create an age_group column:
- 18–29 → Young Adult
- 30–44 → Adult
- 45–59 → Midlife
- 60+ → Senior
Then visualize income vs spending with age group represented by color.
# TODO: Create age_group.
bins = [17, 29, 44, 59, np.inf]
labels = ["Young Adult", "Adult", "Midlife", "Senior"]
# customers["age_group"] = pd.cut(
# customers["age"],
# bins=bins,
# labels=labels
# )
# Your code here
# TODO: Create a scatter plot using hue="age_group".
# Your code here
Reflection
Look for:
- differences in location
- differences in spread
- clusters
- unusual observations
- whether one group appears to follow a different relationship
Then answer:
Does the overall income-spending relationship appear identical across all age groups?
Be cautious. Visual separation is evidence for further investigation, not proof of a causal mechanism.
Project 7 - Categorical Distributions
A product manager asks:
Do customers in different cities have different spending distributions?
A simple average by city may hide important differences.
We will compare distributions instead.
cities = np.array(["Delhi", "Mumbai", "Bengaluru", "Hyderabad", "Pune"])
city_data = pd.DataFrame({
"city": rng.choice(cities, size=2500, p=[0.28, 0.25, 0.20, 0.15, 0.12])
})
city_multipliers = {
"Delhi": 1.00,
"Mumbai": 1.10,
"Bengaluru": 1.18,
"Hyderabad": 0.92,
"Pune": 1.05
}
city_data["spending"] = (
city_data["city"].map(city_multipliers)
* rng.lognormal(mean=np.log(3000), sigma=0.60, size=len(city_data))
)
city_data.head()
city spending
0 Delhi 1539.288882
1 Delhi 4119.115870
2 Delhi 3020.575500
3 Hyderabad 2223.447701
4 Pune 2242.053526Task 7.1 - Box plot by city
Create a Seaborn box plot.
Requirements:
- city on x
- spending on y
- readable category labels
- descriptive title
Then compare:
- median
- spread
- potential outliers
# TODO: Create a box plot of spending by city.
# Your code here
Task 7.2 - Violin plot
Create a violin plot for the same data.
Compare the box plot and violin plot.
Question
What does the violin plot communicate that the box plot communicates less directly?
Consider:
- distribution shape
- density
- multiple peaks
- tails
# TODO: Create a violin plot of spending by city.
# Your code here
Project 8 - Count Plots and Category Imbalance
Not every EDA problem is about numerical variables.
Suppose a company wants to understand the distribution of customers across cities.
Create a count plot.
# TODO: Create a count plot showing the number of customers per city.
# Your code here
Reflection
Answer:
- Which city has the most observations?
- Which city has the fewest?
- Could unequal sample sizes affect comparisons between cities?
- Why might comparing averages alone be dangerous when group sizes differ substantially?
This is an important analytical lesson:
A group with 100 observations and a group with 100,000 observations do not provide the same amount of evidence.
Project 9 - Time-Series Visualization
Time is one of the most common dimensions in real-world data.
The business asks:
How has monthly revenue changed over time?
Create a synthetic daily transaction dataset for two years.
dates = pd.date_range(
"2024-01-01",
"2025-12-31",
freq="D"
)
daily = pd.DataFrame({"date": dates})
# Simulate trend + seasonality + noise
day_number = np.arange(len(daily))
trend = 15000 + day_number * 8
seasonality = 2500 * np.sin(2 * np.pi * day_number / 365.25)
weekly = 900 * np.sin(2 * np.pi * day_number / 7)
daily["revenue"] = (
trend
+ seasonality
+ weekly
+ rng.normal(0, 1200, size=len(daily))
)
daily["revenue"] = daily["revenue"].clip(lower=0)
daily.head()
date revenue
0 2024-01-01 14745.702168
1 2024-01-02 13344.598148
2 2024-01-03 16687.876125
3 2024-01-04 15687.676894
4 2024-01-05 13621.515416Task 9.1 - Daily revenue
Plot daily revenue over time.
Then answer:
- Is there a long-term trend?
- Is there short-term noise?
- Is there visible seasonality?
- Is the daily chart too noisy to communicate the broader trend?
# TODO: Plot daily revenue over time.
# Your code here
Task 9.2 - Aggregate to monthly revenue
Use Pandas to aggregate the daily data to month level.
Then plot monthly revenue.
This is an important EDA concept:
The right aggregation level can make a pattern easier to see.
# TODO:
# 1. Convert date to the index or use a datetime-aware grouping approach.
# 2. Aggregate revenue by month.
# 3. Plot monthly revenue.
# Your code here
Reflection
Compare daily and monthly charts.
Which is better for answering:
"Is the business growing?"
Which is better for answering:
"What happened on a particular day?"
There is no universally best chart. The correct visualization depends on the question.
Project 10 - Rolling Averages
Daily data can be noisy.
A rolling average can help reveal an underlying trend.
Calculate a 30-day rolling mean.
# TODO:
# daily["rolling_30"] = daily["revenue"].rolling(30).mean()
# Your code here
# TODO: Plot original daily revenue and the 30-day rolling mean.
# Your code here
Interpretation
Explain:
- what the rolling average smooths away
- what information it preserves
- what information it hides
- why smoothing can be useful
- why smoothing can also be dangerous
A smoothed chart should complement the raw data, not automatically replace it.
Project 11 - Correlation Heatmap
Now investigate relationships among multiple numerical variables.
Create a richer customer dataset with:
- age
- income
- spending
- purchase frequency
- average order value
- discount usage
- customer tenure
Then calculate a correlation matrix.
n = 1500
analysis_df = pd.DataFrame({
"age": rng.integers(18, 70, n),
"income": rng.lognormal(np.log(70000), 0.5, n),
"purchase_frequency": rng.poisson(12, n) + 1,
"avg_order_value": rng.lognormal(np.log(2500), 0.45, n),
"discount_usage": rng.uniform(0, 1, n),
"tenure_months": rng.integers(1, 84, n)
})
analysis_df["spending"] = (
analysis_df["purchase_frequency"]
* analysis_df["avg_order_value"]
* rng.normal(1, 0.15, n)
)
analysis_df["spending"] = analysis_df["spending"].clip(lower=0)
analysis_df.head()
age income purchase_frequency avg_order_value discount_usage \
0 20 74090.530696 13 4234.866952 0.468029
1 24 57260.181716 11 3145.353805 0.652322
2 20 87224.130899 8 2889.292160 0.168342
3 44 129797.302477 8 3827.983927 0.976808
4 66 160826.652201 14 2177.870845 0.580554
tenure_months spending
0 45 50826.114423
1 36 36942.120070
2 26 23181.810442
3 24 32766.177771
4 54 29176.486552 Task 11.1 - Correlation matrix
Calculate correlations among all numerical variables.
Then visualize them using a Seaborn heatmap.
Requirements:
- annotate correlation values
- use a clear title
- make the figure large enough to read
# TODO: Create the correlation matrix and heatmap.
# Your code here
Interpretation exercise
Find:
- the strongest positive relationship
- the strongest negative relationship
- a relationship close to zero
For each, write one sentence describing what the correlation suggests.
Then write:
"Correlation does not establish causation because..."
Complete the sentence in your own words.
Project 12 - Pair Plot Investigation
A pair plot can provide a fast overview of relationships among a small set of variables.
Select:
- income
- spending
- purchase frequency
- average order value
Create a pair plot.
# TODO: Create a pair plot for selected numerical variables.
# Your code here
Why pair plots should be used carefully
Pair plots are useful for exploration, but they have limitations:
- they become unreadable with many variables
- large datasets can produce dense plots
- correlation may be visually difficult to assess
- categorical structure may be hidden
- they encourage broad exploration rather than focused questions
Use them as an investigative tool, not as a substitute for thoughtful analysis.
Project 13 - Faceting
Suppose the relationship between income and spending may differ by customer segment.
Create a customer_segment variable based on income.
Then use Seaborn's FacetGrid or relplot() to create separate scatter plots for each segment.
analysis_df["customer_segment"] = pd.qcut(
analysis_df["income"],
q=3,
labels=["Low Income", "Middle Income", "High Income"]
)
analysis_df["customer_segment"].value_counts()
customer_segment
Low Income 500
Middle Income 500
High Income 500
Name: count, dtype: int64# TODO: Create faceted scatter plots of income vs spending by customer_segment.
# Hint:
# sns.relplot(
# data=analysis_df,
# x="income",
# y="spending",
# col="customer_segment",
# kind="scatter"
# )
# Your code here
Reflection
Compare the faceted plots.
Ask:
- Does the relationship look consistent across groups?
- Does the spread change?
- Are there different outliers?
- Does segmentation reveal a pattern that the single overall scatter plot hides?
This is an example of how stratification can reveal structure hidden in aggregate data.
Project 14 - Build a Mini EDA Dashboard
Now combine multiple visualizations into a coherent analytical story.
Scenario
You are presenting to a product manager who has five minutes.
They want to know:
- What does customer spending look like?
- Which city has the highest typical spending?
- Is income associated with spending?
- How large is the customer base by city?
- Are there unusual high-value customers?
Create a set of five separate figures, one for each question.
Do not put everything into one overcrowded chart.
Required charts
Figure 1
Spending distribution.
Figure 2
Spending by city.
Figure 3
Income vs spending.
Figure 4
Customer count by city.
Figure 5
Outlier-focused spending visualization.
For every figure, include:
- title
- axis labels
- units
- appropriate scale
- readable categories
- a short Markdown interpretation
# TODO: Build your five-chart mini dashboard.
# Figure 1: spending distribution
# Figure 2: spending by city
# Figure 3: income vs spending
# Figure 4: customer count by city
# Figure 5: outlier-focused visualization
# Your code here
Project 15 - Visualization Critique
A strong analyst should be able to critique visualizations, not merely create them.
For each chart below, imagine that it has been presented to a stakeholder.
Evaluate:
- Is the chart appropriate?
- Is the scale appropriate?
- Is the title informative?
- Are the units clear?
- Is the comparison easy?
- Could the chart mislead?
- What alternative chart might be better?
Critique A
A pie chart with 25 categories showing product revenue.
Questions:
- Is a pie chart appropriate?
- Can viewers accurately compare many slices?
- Would a sorted bar chart be better?
Critique B
A line chart with 10,000 daily observations and no aggregation.
Questions:
- Is the chart too noisy?
- Would weekly or monthly aggregation help?
- Should the raw series still be available?
Critique C
A bar chart with a y-axis starting at 95 instead of 0, showing values of 96, 97, and 98.
Questions:
- Does the truncated axis exaggerate differences?
- When can a non-zero baseline be appropriate?
- What should be communicated explicitly?
Critique D
A scatter plot containing 2 million points.
Questions:
- Will overplotting hide patterns?
- Could sampling help?
- Could transparency help?
- Could hexbin or density visualization be more appropriate?
Project 16 - Tell a Data Story
This is the most important project in the notebook.
You will produce an analytical narrative rather than a collection of charts.
Your task
Choose one dataset you care about.
Possible themes:
- movies
- sports
- music
- gaming
- finance
- e-commerce
- education
- climate
- transportation
- housing
- public policy
- technology
- social media
Define one central question.
Example:
What factors are associated with higher movie ratings?
Then build a visualization story.
Required structure
1. Question
State the question in one or two sentences.
2. Dataset
Explain:
- source
- observations
- variables
- time period
- known limitations
3. Data quality
Investigate:
- missing values
- duplicates
- invalid values
- inconsistent categories
- suspicious outliers
4. Univariate exploration
At least two variables.
5. Bivariate exploration
At least two relationships.
6. Multivariate exploration
At least one analysis involving three or more variables.
7. Visualization
Create at least five meaningful charts.
8. Findings
Write at least five findings.
9. Limitations
Write at least three limitations.
10. Next questions
Write at least five questions that would be worth investigating next.
Project 17 - Advanced Challenge: Reproduce a Visualization
Find an interesting visualization online or in a public report.
Do not copy the underlying data blindly.
Instead:
- identify the analytical question
- identify the chart type
- identify the variables
- identify the visual encodings
- recreate the visualization using Python
- improve one aspect of it
- explain your design choices
Your goal is to learn visualization by reverse-engineering good examples.
Questions to answer
- Why did the original author choose this chart?
- What is the most important visual element?
- How is attention directed?
- What would make the visualization easier to understand?
- What information could be lost?
Project 18 - Advanced Challenge: Make a Bad Chart Better
Create an intentionally poor chart.
Examples:
- too many categories
- unclear title
- missing units
- unreadable labels
- excessive clutter
- poor chart type
- misleading scale
Then redesign it.
Your notebook should contain:
- the bad chart
- an explanation of what is wrong
- the improved chart
- an explanation of each improvement
This teaches an important skill:
Visualization is communication design.
Project 19 - Analytical Writing Challenge
For each major chart in your final project, write three layers of interpretation.
Layer 1 - Observation
What can we directly see?
Example:
"Revenue is highest in the fourth quarter."
Layer 2 - Interpretation
What might explain the pattern?
Example:
"This may indicate seasonal demand."
Layer 3 - Limitation
What can we not conclude?
Example:
"The chart alone cannot determine whether seasonality caused the increase."
This three-layer structure helps prevent overclaiming.
Project 20 - Final Capstone
Build an EDA Visualization Portfolio
Create a final notebook using a real dataset.
Your submission should demonstrate all major skills from this notebook.
Required analytical components
A. Dataset overview
Show:
- shape
- columns
- data types
- sample rows
- descriptive statistics
B. Data-quality analysis
Show:
- missing values
- duplicates
- categorical consistency
- suspicious numerical values
C. Univariate analysis
Include:
- at least one histogram
- at least one count plot
- at least one box plot
D. Bivariate analysis
Include:
- at least one scatter plot
- at least one categorical comparison
E. Multivariate analysis
Include at least one:
- heatmap
- faceted chart
- hue-based visualization
- pair plot
F. Time analysis
If your dataset contains dates, include:
- a time-series chart
- an appropriate aggregation
- interpretation of trends
If your dataset has no dates, explain why time-series analysis is not applicable.
G. Outlier analysis
Identify and investigate at least one unusual observation or group.
H. Findings
Write at least five meaningful findings.
I. Limitations
Write at least three limitations.
J. Next steps
Write at least five follow-up questions.
Final Assessment Rubric
Use this rubric before considering the project complete.
| Area | Beginner | Developing | Strong |
|---|---|---|---|
| Chart selection | Uses familiar charts | Usually appropriate | Consistently question-driven |
| Matplotlib | Basic plots | Customizes plots | Strong control and polish |
| Seaborn | Basic usage | Uses statistical plots | Uses hue/faceting/distributions effectively |
| Data understanding | Describes columns | Connects variables to questions | Understands analytical context |
| Distribution analysis | Makes histograms | Interprets shape | Connects distribution to decisions |
| Relationship analysis | Makes scatter plots | Discusses correlation | Investigates confounding and segmentation |
| Outliers | Identifies extremes | Investigates them | Distinguishes anomalies from legitimate rare events |
| Time series | Creates line chart | Aggregates appropriately | Explains trend/seasonality/noise |
| Communication | Gives chart titles | Explains findings | Builds a coherent analytical story |
| Statistical caution | Avoids obvious errors | Understands correlation | Consistently distinguishes evidence from causation |
| Reproducibility | Code runs | Organized notebook | Clear, reusable, documented workflow |
Final Checklist
Before submitting your notebook, verify:
Code
- [ ] All imports are included.
- [ ] Code runs from top to bottom.
- [ ] Random operations use a fixed seed where appropriate.
- [ ] Variables have meaningful names.
- [ ] Repeated logic is avoided where possible.
- [ ] Charts render correctly.
Data
- [ ] You understand what each row represents.
- [ ] You understand the important variables.
- [ ] Missing data has been investigated.
- [ ] Duplicates have been investigated.
- [ ] Outliers have been investigated.
- [ ] Categories have been checked.
- [ ] Dates have been parsed correctly when applicable.
Visualization
- [ ] Every chart answers a question.
- [ ] Every chart has a descriptive title.
- [ ] Axes are labeled.
- [ ] Units are explicit.
- [ ] Categories are readable.
- [ ] Scales are appropriate.
- [ ] Visual clutter is minimized.
- [ ] Colors have a purpose.
- [ ] You avoid unnecessary decoration.
Interpretation
- [ ] You distinguish observation from interpretation.
- [ ] You do not claim causation from correlation alone.
- [ ] You discuss important limitations.
- [ ] You identify potential confounders.
- [ ] You identify useful follow-up questions.
Communication
- [ ] Someone unfamiliar with your code can understand the story.
- [ ] Markdown explains why each analysis exists.
- [ ] Findings are written in plain language.
- [ ] The conclusion answers the original question.
- [ ] The notebook ends with clear next steps.
Final Challenge: Think Like an Analyst
Before moving to the next phase, complete this exercise without writing code.
You receive a dataset containing:
customer_id
age
city
income
product
quantity
price
purchase_dateA stakeholder asks:
"Tell me something interesting about our customers."
Do not immediately make a chart.
Write down:
Step 1 - Questions
What would you want to know?
Step 2 - Assumptions
What do you need to understand about the dataset?
Step 3 - Quality checks
What could be wrong?
Step 4 - Variables
Which variables might be useful?
Step 5 - Visualizations
Which charts would help answer your questions?
Step 6 - Interpretation
What would count as a meaningful finding?
Step 7 - Next steps
What would you investigate after discovering an interesting pattern?
This exercise is the real objective of Phase 1.
What You Should Take Away
Matplotlib and Seaborn are not the skill.
The skill is visual reasoning.
You should now be moving from:
"I know how to make a scatter plot."
to:
"I know when a scatter plot is useful."
Then from:
"I found a correlation."
to:
"I found an association, and I understand what it does and does not establish."
And finally from:
"Here are five charts."
to:
"Here is a question, here is the evidence, here is what the evidence suggests, here are the limitations, and here is what I would investigate next."
That is the foundation of strong Exploratory Data Analysis.
Next Phase
Once you can independently investigate a dataset with NumPy, Pandas, Matplotlib, and Seaborn, you are ready to move from:
Exploring datatoward:
Using data to answer questions systematically.The next phase should build on this foundation rather than skipping it.
Do not rush past EDA.
The ability to understand data before modeling it is one of the most important skills in the entire data-science and AI workflow.
Finished this lesson?
Keep your place here, or save it across devices with an email link.
Saved in this browser. Save progress with email →