Analyze Titanic Data with pandas

Load, clean, and analyze real Titanic passenger data to find survival patterns.

Introduction

30 Second Summary

Over 2,200 people boarded the Titanic, but only about 700 survived. The passenger records from that night still exist, and buried in those records are patterns that reveal who had the best chance of making it out alive.

In this project, you will write a Python script that uses pandas to load real Titanic passenger data, clean up messy gaps in the records, and uncover survival patterns by class, sex, and age group. Your script finishes by generating a bar chart that makes the class divide instantly visible.

What You'll Build

Run your finished script and watch survival statistics print to your terminal, followed by a matplotlib chart window that reveals 1st class passengers survived at nearly triple the rate of 3rd class.

By the end of this project, you'll have:

  • A working Python script you can run to see survival statistics in your terminal, broken down by passenger class, sex, and age group.
  • A saved bar chart image comparing survival rates across 1st, 2nd, and 3rd class passengers.
  • The confidence to modify your analysis and explore new questions, like "Did having family onboard help?"
  • Secret Mission: Build a Passenger Survival Profiler function that takes any passenger's details and reports their survival odds.

Are there any prerequisites?

No prior Python or data analysis experience is needed. This project includes setup instructions for every tool along the way.

Before We Start

Before diving in, take a moment to think about what you are building and why it matters for your goals.

Set Up Your Python Project

Python can read files and do math on its own, but it doesn't know how to work with data tables or create charts out of the box. You need two add-on libraries for that: pandas for data analysis, and matplotlib for visualization.

Installing libraries directly into your system Python can cause conflicts between projects. To keep things clean, you'll create a virtual environment. This is a dedicated workspace that keeps your project's libraries separate from everything else on your machine.

In this step, get ready to:
  • Create a project folder and a virtual environment to keep your tools organized.
  • Install the pandas and matplotlib libraries.
  • Download the Titanic passenger dataset.
Create a project folder and virtual environment

Before you can write any code, you need a dedicated folder for this project and a terminal open to run commands from.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type VS Code and press Enter to open it.
  • Open a new terminal inside VS Code by pressing Ctrl+` (the backtick key, usually above Tab).
  • Move to your Desktop and create your project folder by running these commands:
cd ~/Desktop
mkdir titanic-analysis
cd titanic-analysis

What do these commands do?

  • cd ~/Desktop moves your terminal to the Desktop folder so your project is easy to find later.
  • mkdir titanic-analysis creates a new folder called titanic-analysis.
  • cd titanic-analysis moves into that new folder so every command from here runs inside it.

Your terminal prompt now shows titanic-analysis in the path, confirming you're in the right folder.

  • Create and activate a virtual environment by running these commands:
python -m venv venv
.\venv\Scripts\Activate

What is a virtual environment?

A virtual environment is a self-contained folder that holds its own copy of Python and any libraries you install. Anything you install while the virtual environment is active stays inside the venv folder and won't affect other projects on your machine.

  • python -m venv venv creates this isolated folder (named venv) inside your project.
  • .\venv\Scripts\Activate tells your terminal to use this isolated Python instead of your system-wide one.
  • Check your terminal prompt. You should see (venv) appear at the very start, confirming the virtual environment is active.

Activation not working?

  • If you see an error containing cannot be loaded because running scripts is disabled on this system, your PowerShell execution policy is blocking the activation script. Run Set-ExecutionPolicy -Scope CurrentUser RemoteSigned in your terminal, then try the activation command again.
  • Make sure you're running the command from inside the titanic-analysis folder. The venv folder must exist in your current directory.
  • help me activate my Python virtual environment in VS Code
Install pandas and matplotlib

With your virtual environment active, any libraries you install now go into this project's isolated workspace.

  • Install both libraries by running this command:
pip install pandas==3.0.5 matplotlib==3.11.1

What does this command do?

  • pip install downloads and installs Python packages from PyPI, the Python Package Index.
  • pandas==3.0.5 pins the exact version so your project uses the same version as this guide.
  • matplotlib==3.11.1 does the same for the charting library.
  • Wait for the installation to finish. You should see Successfully installed followed by a list of package names near the bottom of the output.

Install failing?

  • Make sure (venv) appears in your terminal prompt. If it doesn't, the virtual environment isn't active. Run .\venv\Scripts\Activate first.
  • If you see a network error, check your internet connection and try the command again.
  • help me install pandas and matplotlib in my Python virtual environment
Download the Titanic dataset

You need actual data to analyze. The Titanic passenger dataset is a classic beginner dataset with a mix of numbers, text, and missing values.

  • Download the dataset into your project folder by running this command:
curl.exe -o titanic.csv "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"

What does this command do?

  • curl.exe downloads a file from the internet directly to your terminal. On Windows, using curl.exe (with the .exe) calls the real download tool instead of a PowerShell shortcut that behaves differently.
  • -o titanic.csv tells it to save the downloaded file as titanic.csv in your current folder.

Browser alternative

If curl.exe doesn't work, open this URL in your browser: https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv. Right-click the page, choose Save As, and save the file as titanic.csv inside your titanic-analysis folder on the Desktop.

  • Confirm the file downloaded by running:
dir titanic.csv
  • You should see titanic.csv listed with its file size. This file contains 891 rows of real Titanic passenger data.

File not showing up?

  • Make sure your terminal is still inside the titanic-analysis folder. Run cd by itself to check your current directory.
  • If you used the browser to download the file, double-check that you saved it inside the titanic-analysis folder on your Desktop, not in your Downloads folder.
  • help me download the Titanic CSV dataset into my project folder

Everything is installed and the data is ready. Before you move on, predict: if you try to import pandas and matplotlib right now, do you think Python will find them?

  • Verify your entire setup by running this command:
python -c "import pandas; import matplotlib; print('Ready!')"

You should see Ready! printed in your terminal. This confirms Python can find both libraries inside your virtual environment.

Your environment is locked and loaded. Next up, you'll write your first lines of Python to load the Titanic data and see real passenger records in your terminal.

Load the Data and Run Your First Analysis

Your project environment is set up with pandas and matplotlib installed. Now it is time to see what the Titanic dataset actually looks like.

Before you can find patterns, you need to load the data into Python and confirm it reads correctly. In this step, you will create your first Python script and see real passenger data in your terminal.

In this step, get ready to:
  • Load Titanic passenger data into a pandas DataFrame.
  • Preview the first rows and check the dataset dimensions.
  • Calculate the overall survival rate from the raw data.
Create your Python file and load the data

Every Python project starts with a script file. You will create one now and write the code that loads your CSV data into a table Python can work with.

  • In VS Code, click File in the top menu bar.
  • Click Open Folder.
  • Select the titanic-analysis folder on your Desktop, then click Select Folder.

Why open the folder?

Opening the folder in VS Code gives you the Explorer sidebar, which shows all your project files in one place. It also makes sure any new files you create land in the right folder.

  • In the Explorer sidebar on the left, hover over the titanic-analysis folder name.
  • Click the New File icon that appears (it looks like a page with a small plus sign).
  • Type analyze.py and press Enter.

VS Code opens the empty file in the editor. You should also see titanic.csv listed in the Explorer alongside your new file.

  • Add the following code to analyze.py to import pandas, load the CSV, and print the first rows:
# Import pandas for data analysis
import pandas as pd

# Load the Titanic dataset into a DataFrame
df = pd.read_csv("titanic.csv")

# Display the first 5 rows to preview the data
print("=== First 5 Rows ===")
print(df.head())
print()
# Show how many rows and columns the dataset has
print(f"Dataset: {df.shape[0]} rows, {df.shape[1]} columns")

What does this code do?

  • import pandas as pd loads the pandas library and gives it the shortcut name pd so you can type less.
  • pd.read_csv("titanic.csv") reads the CSV file and creates a DataFrame. A DataFrame is a table of rows and columns, similar to a spreadsheet.
  • df.head() returns the first 5 rows so you can quickly see what the data looks like.
  • df.shape gives you the number of rows and columns. f"..." is an f-string, which lets you insert variables directly into text using curly braces.
  • Save analyze.py by pressing Cmd+S (macOS) or Ctrl+S (Windows).
  • Open a terminal in VS Code by pressing Ctrl+` (backtick key, usually above Tab).
  • Make sure you see (venv) at the start of your terminal prompt. If not, activate the virtual environment by running:
.\venv\Scripts\Activate
  • Run your script by running this command:
python analyze.py

You should see a table showing the first 5 passengers with columns like Name, Sex, and Age. Below it, you should see Dataset: 891 rows, 12 columns.

Seeing a FileNotFoundError?

  • Make sure titanic.csv is saved directly inside the titanic-analysis folder, not in a subfolder.
  • Check that your terminal's current directory is titanic-analysis. You can verify by looking at the folder path shown in the terminal prompt.
  • Confirm the file name is exactly titanic.csv (lowercase, no extra spaces).

Why can't Python find my titanic.csv file?

Calculate the overall survival rate

You can see the data, but a table of rows does not answer any questions on its own. The Survived column holds the answer to the most basic question: how many passengers made it?

  • In analyze.py, add these lines at the bottom of the file:
# Count survivors and calculate the survival percentage
survived = df["Survived"].sum()
total = len(df)
rate = survived / total * 100
print(f"Survived: {survived} out of {total} passengers ({rate:.1f}%)")

What does this code do?

  • df["Survived"] grabs just the Survived column. Each value is either 1 (survived) or 0 (did not survive).
  • .sum() adds up all the 1s, giving you the total number of survivors.
  • len(df) counts the total number of rows in the DataFrame.
  • :.1f inside the f-string formats the number to 1 decimal place, so you see 38.4 instead of a long decimal.

Before you run the script, take a guess. Do you think more than half the passengers survived, or fewer?

  • Save analyze.py.
  • Run the script again by running this command:
python analyze.py

You should see all the previous output, plus a new line at the bottom: Survived: 342 out of 891 passengers (38.4%). Fewer than 4 in 10 passengers survived.

Seeing a KeyError or NameError?

  • A KeyError means the column name does not match. Check that you typed Survived with a capital S.
  • A NameError means Python does not recognize a variable. Make sure the new lines are below the df = pd.read_csv("titanic.csv") line, not above it.
  • Check that every quotation mark and parenthesis is properly closed. A missing quote will cause a SyntaxError.

Help me debug my analyze.py script

✔️ Awesome, I've got everything!

Great. Double check you have saved analyze.py before moving on.

ⓧ I'd like to double check the full code

Here is the complete analyze.py file so far. Compare it against yours line by line.

# Import pandas for data analysis
import pandas as pd

# Load the Titanic dataset into a DataFrame
df = pd.read_csv("titanic.csv")

# Display the first 5 rows to preview the data
print("=== First 5 Rows ===")
print(df.head())
print()
# Show dataset dimensions
print(f"Dataset: {df.shape[0]} rows, {df.shape[1]} columns")

# Count survivors and calculate the survival percentage
survived = df["Survived"].sum()
total = len(df)
rate = survived / total * 100
print(f"Survived: {survived} out of {total} passengers ({rate:.1f}%)")

You have loaded real passenger data and calculated the overall survival rate: only 38.4% survived. But one number does not tell the whole story. In the next step, you will slice the data by age group to uncover who had the best chances.

Break Down Survival by Age Group

You loaded the Titanic dataset and found that 342 out of 891 passengers survived. That's 38.4%, but one number alone doesn't reveal who survived. Was it random, or do clear patterns exist?

To find out, you need to slice the data into categories and compare them. In this step, you'll write your first Python function to group passengers by age. The results will reveal a problem hiding in the data.

In this step, get ready to:
  • Write a get_age_group function using if/elif/else logic.
  • Apply the function to create a new AgeGroup column in your DataFrame.
  • Run the script and examine the age group distribution.
Write a function to categorize ages

Right now every passenger has a raw age number. A function can turn those numbers into meaningful categories like "Child", "Teen", "Adult", and "Senior" so you can compare groups instead of hundreds of individual ages.

  • In analyze.py, add this function below your existing code:
# Categorize a passenger's age into a group
def get_age_group(age):
    if age < 13:
        return "Child"
    elif age < 20:
        return "Teen"
    elif age < 60:
        return "Adult"
    else:
        return "Senior"

What does this code do?

  • def creates a function. get_age_group takes a single number (age) and returns a category name.
  • if/elif/else checks conditions in order. Python runs the first branch that matches and skips the rest.
  • Python uses indentation (spaces) instead of curly braces to mark which lines belong to each branch.
  • Save analyze.py.
Apply the function to create a new column

The function exists, but it isn't doing anything yet. You need to run it on every passenger's age and store the results in a new column.

  • Add these lines below the get_age_group function:
# Run get_age_group on every value in the Age column
df["AgeGroup"] = df["Age"].apply(get_age_group)

# Print how many passengers are in each group
print()
print("=== Passengers by Age Group ===")
print(df["AgeGroup"].value_counts())

What does this code do?

  • .apply(get_age_group) runs your function on every single value in the Age column. Each passenger gets categorized automatically.
  • df["AgeGroup"] = ... creates a brand new column in your DataFrame called AgeGroup.
  • .value_counts() counts how many passengers landed in each group and sorts from most to least.
  • Save analyze.py.

✔️ Awesome, I've got everything!

Great. Double check you've saved your file before running it in the next substep.

ⓧ I'd like to double check the full code

Here's the full analyze.py file so far. Make sure yours matches before continuing.

import pandas as pd

df = pd.read_csv("titanic.csv")

print("=== First 5 Rows ===")
print(df.head())
print()
print(f"Dataset: {df.shape[0]} rows, {df.shape[1]} columns")

survived = df["Survived"].sum()
total = len(df)
rate = survived / total * 100
print(f"Survived: {survived} out of {total} passengers ({rate:.1f}%)")

def get_age_group(age):
    if age < 13:
        return "Child"
    elif age < 20:
        return "Teen"
    elif age < 60:
        return "Adult"
    else:
        return "Senior"

df["AgeGroup"] = df["Age"].apply(get_age_group)

print()
print("=== Passengers by Age Group ===")
print(df["AgeGroup"].value_counts())
Run and spot the problem

Before you run the script, take a guess. Out of 891 passengers on a ship in 1912, how many do you expect to be in the "Senior" group (age 60 and above)?

  • Run your script by entering this command:
python analyze.py

Scroll down to the === Passengers by Age Group === section. The "Senior" group has around 200+ entries. On a real ship, that is far too many senior citizens.

This is intentional

Your analysis is silently wrong. 177 passengers have missing Age data (stored as NaN, which stands for "Not a Number").

When Python compares NaN to a number, every comparison returns False. So NaN < 13 is False, NaN < 20 is False, and NaN < 60 is False. All 177 missing ages fall through every if and elif branch and land in the else ("Senior") branch.

The data needs cleaning before you can trust any analysis built on top of it.

Seeing a different error instead?

  • If you see IndentationError, check that every line inside the get_age_group function is indented with exactly 4 spaces (or one tab). The if, elif, and else lines should be at the same level, and each return line should be indented one more level inside its branch.
  • If you see NameError: name 'get_age_group' is not defined, make sure the function definition appears above the line that calls df["Age"].apply(get_age_group). Python reads top to bottom.

Help me debug my get_age_group function in analyze.py

Your function works perfectly on real ages, but the dataset has 177 holes where ages should be. In the next step, you'll find and fix every gap so the analysis is accurate.

Clean the Messy Data

In the last step, you saw that the Senior age group had 200+ entries. That is way too many senior citizens for one ship. The root cause is 177 passengers with missing Age data, and Python quietly shoved them all into the wrong category.

Missing values are the most common problem in real-world datasets. In this step, you will find every gap in the data, fix them, and then re-run your age group analysis to see the difference.

In this step, get ready to:
  • Find all missing values in the dataset.
  • Fill or remove the gaps to clean the data.
  • Verify the fix by confirming zero missing values and realistic age group counts.
Find all the missing values

Before you can fix the gaps, you need to know exactly where they are. pandas has a built-in method that counts missing values in every column at once.

  • In analyze.py, find the line that says:
  • Also add a print() line directly after print(f"Dataset: {df.shape[0]} rows, {df.shape[1]} columns") to add spacing in the output.
print(f"Survived: {survived} out of {total} passengers ({rate:.1f}%)")
  • Add this code right below that line, before the get_age_group function:
print()
print("=== Missing Values ===")
print(df.isnull().sum())

What does this code do?

  • .isnull() marks every cell as True (missing) or False (has data).
  • .sum() counts the True values per column, giving you the total number of gaps.
  • Save analyze.py and run the script with this command:
python analyze.py

In the Missing Values section, you should see Age has 177 missing values, Cabin has 687, and Embarked has 2.

Not seeing the missing values section?

  • Make sure the new code is placed after the print(f"Survived:...") line and before the def get_age_group(age): function.
  • Check that you saved the file before running the script.
  • help me debug why my missing values output is not showing up
Fill and drop to clean the data

Now you know where the gaps are. The strategy is to fill Age and Embarked with reasonable substitute values, and drop columns that are too empty or not useful for survival analysis.

  • In analyze.py, add this code right after the print(df.isnull().sum()) line you just added, still before the get_age_group function:
df["Age"] = df["Age"].fillna(df["Age"].median())
df["Embarked"] = df["Embarked"].fillna("S")
df = df.drop(columns=["Cabin", "Ticket", "Name", "PassengerId"])

print()
print("Missing values after cleaning:")
print(df.isnull().sum())

What does this code do?

  • .fillna(df["Age"].median()) replaces every missing age with the median (middle value) of all known ages. This is a standard technique in data science because the median is not skewed by extreme values.
  • .fillna("S") fills the 2 missing Embarked values with "S" (Southampton, the most common port).
  • .drop(columns=[...]) removes columns you do not need for analysis. Cabin is 77% empty, and Name, Ticket, and PassengerId are not useful for survival analysis.

The cleaning code now runs before get_age_group, so the function will process clean data with zero missing values.

  • Scroll down to the line that says:
print()
print("=== Passengers by Age Group ===")
  • Delete the print() line so only print("=== Passengers by Age Group ===") remains. The cleaning section you just added already handles the spacing above it.
print("=== Passengers by Age Group ===")
Verify the fix

Before you run the script, think about what you expect to see. Do you think the Senior count will still be 200+, or will it drop now that the missing ages are filled?

  • Save analyze.py and run the script:
python analyze.py

The "Missing values after cleaning" output should show 0 for every column. The AgeGroup counts should now look realistic, with the Senior count dropping from 200+ to around 30-40.

What changed?

Those 177 passengers who had missing ages are no longer falling into the "Senior" bucket. They now have the median age (28.0) filled in, so they land correctly in the "Adult" group instead.

Compare the AgeGroup distribution to what you saw in the last step. The Senior count shrank dramatically, and Adult grew. That is the difference between trusting dirty data and cleaning it first.

Still seeing missing values after cleaning?

  • Make sure the fillna() and drop() lines are placed after the first print(df.isnull().sum()) and before the get_age_group function.
  • Check that you are reassigning the result back to df with df["Age"] = ... and df = df.drop(...). Without the reassignment, the original data stays unchanged.
  • help me figure out why I still have missing values after cleaning

✔️ Awesome, I've got everything!

Great. Double check you have saved analyze.py before moving on.

ⓧ I'd like to double check the full code

Your analyze.py file should have these sections in order. Scroll up and confirm each one is present:

  • import pandas as pd at the top.
  • pd.read_csv("titanic.csv") to load the data.
  • The "First 5 Rows" and "Dataset" print section, ending with print().
  • The survival rate calculation (survived, total, rate).
  • The "Missing Values" print with df.isnull().sum().
  • The three cleaning lines: fillna() for Age, fillna() for Embarked, drop() for unused columns.
  • The "Missing values after cleaning" print with df.isnull().sum(), followed by print().
  • The get_age_group function definition.
  • df["AgeGroup"] = df["Age"].apply(get_age_group) followed by the age group print.

Your data is clean and your analysis is trustworthy. Next up, you will slice the cleaned data with groupby() to reveal who really had the best chance of surviving, and turn those numbers into a chart.

Analyze Survival Patterns and Create a Chart

In the last step, you cleaned 177 missing ages and dropped columns full of gaps. Your data is now trustworthy, with zero missing values across every column.

Now you can answer the big question: who was most likely to survive the Titanic? You will slice the data by class, sex, and age group using pandas groupby, then build a bar chart with matplotlib that turns raw numbers into a visual story.

In this step, get ready to:
  • Compute survival rates by class, sex, and age group using groupby.
  • Create a bar chart showing survival rates by passenger class.
  • Save the chart as a PNG image file.
Compute survival rates with groupby

A single survival percentage (38.4%) does not tell you whether class, sex, or age made a difference. Groupby lets you split the data into categories and calculate the survival rate for each one separately.

  • In analyze.py, scroll to the very bottom of the file.
  • Find these last two lines:
print("=== Passengers by Age Group ===")
print(df["AgeGroup"].value_counts())
  • Delete these two lines and replace them with the following code:
# Survival rate by passenger class
print("=== Survival Rate by Class ===")
class_survival = df.groupby("Pclass")["Survived"].mean() * 100
for pclass, survival_rate in class_survival.items():
    print(f"  Class {pclass}: {survival_rate:.1f}%")

# Survival rate by sex
print()
print("=== Survival Rate by Sex ===")
sex_survival = df.groupby("Sex")["Survived"].mean() * 100
for sex, survival_rate in sex_survival.items():
    print(f"  {sex.capitalize()}: {survival_rate:.1f}%")

# Survival rate by age group
print()
print("=== Survival Rate by Age Group ===")
age_survival = df.groupby("AgeGroup")["Survived"].mean() * 100
for group, survival_rate in age_survival.items():
    print(f"  {group}: {survival_rate:.1f}%")

What does this code do?

Each block follows the same pattern. .groupby("Pclass") splits the data into groups by passenger class (1st, 2nd, 3rd). Then ["Survived"].mean() calculates the average of the Survived column for each group.

Because Survived is 0 (died) or 1 (survived), the mean IS the survival rate. Multiplying by 100 converts it to a percentage. The for loop walks through each group and prints its rate.

  • Save analyze.py.
  • Before you run the script, take a guess: which passenger class do you think had the highest survival rate?
  • Run the script by entering this command in your terminal:
python analyze.py

You should see survival rates broken down by class, sex, and age group. The patterns are stark: 1st class passengers survived far more often than 3rd class, and women survived far more often than men.

Seeing a NameError or KeyError?

  • If you see NameError: name 'class_survival' is not defined, make sure you deleted the old value_counts() lines and pasted the new groupby code in the same spot (at the very bottom of the file).
  • If you see KeyError: 'AgeGroup', the new code might have been pasted above the df["AgeGroup"] = df["Age"].apply(get_age_group) line. The groupby code must come after the AgeGroup column is created.
  • Still stuck? Help me debug my groupby survival rate code in analyze.py.
Add the matplotlib import and create a bar chart

Numbers in a terminal are convincing, but a chart makes the class divide instantly visible. You will use matplotlib to draw a bar chart comparing survival rates across 1st, 2nd, and 3rd class.

  • In analyze.py, scroll to the very top of the file.
  • Find this line:
import pandas as pd
  • Add a new line directly below it so your imports look like this:
import pandas as pd
import matplotlib.pyplot as plt
  • Now scroll to the very bottom of analyze.py and add the following chart code below your last groupby block:
# Compute survival rates by class for the chart
survival_by_class = df.groupby("Pclass")["Survived"].mean() * 100

plt.figure(figsize=(8, 5))
bars = plt.bar(
    ["1st Class", "2nd Class", "3rd Class"],
    survival_by_class.values,
    color=["#2ecc71", "#3498db", "#e74c3c"],
)

# Add percentage labels on top of each bar
for bar in bars:
    height = bar.get_height()
    plt.text(
        bar.get_x() + bar.get_width() / 2,
        height + 1,
        f"{height:.1f}%",
        ha="center",
        fontsize=12,
    )

plt.title("Titanic Survival Rate by Passenger Class", fontsize=14)
plt.xlabel("Passenger Class", fontsize=12)
plt.ylabel("Survival Rate (%)", fontsize=12)
plt.ylim(0, 100)
plt.tight_layout()
plt.savefig("survival_by_class.png")
print()
print("Chart saved as survival_by_class.png")
plt.show()

What does this chart code do?

  • plt.figure(figsize=(8, 5)) creates a chart canvas 8 inches wide and 5 inches tall.
  • plt.bar() draws the bars. Each bar gets a label ("1st Class", etc.), a height (the survival rate), and a color.
  • The for bar in bars: loop places a percentage label on top of each bar so the exact rate is readable.
  • plt.savefig() saves the chart as an image file. plt.show() opens a window so you can see it on screen.
  • Save analyze.py.
Run and see the results

Your script now cleans data, computes survival rates, and generates a chart. Before you run it, think about what you expect to see: will the chart open automatically, or do you need to open it yourself?

  • Run the full script by entering this command:
python analyze.py

You should see survival rates for class, sex, and age group printed in your terminal. A chart window opens automatically showing the bar chart comparing 1st, 2nd, and 3rd class survival rates.

Why does the terminal pause?

plt.show() opens an interactive chart window and pauses the script until you close it. Close the chart window to let the script finish and return control to your terminal.

  • Close the chart window.
  • Confirm the chart image was saved by running:
dir survival_by_class.png

You should see survival_by_class.png listed in the output. This file is a standalone image you could attach to a report or show in an interview.

Chart window not appearing?

  • Make sure import matplotlib.pyplot as plt is at the top of your file, directly below the pandas import. If this line is missing, Python does not know what plt means.
  • Check that your virtual environment is still active. You should see (venv) at the start of your terminal prompt. If not, reactivate it with .\venv\Scripts\Activate.
  • If the chart window appeared but was hidden behind VS Code, check your taskbar for a matplotlib window.
  • Still stuck? Help me fix my matplotlib chart in analyze.py.

✔️ Awesome, I've got everything!

Great. Double check you have saved analyze.py and that survival_by_class.png exists in your project folder.

ⓧ I'd like to double check the full code

Your analyze.py file should contain these sections in order. Scroll through your file and confirm each one is present:

  • Two imports at the top: import pandas as pd and import matplotlib.pyplot as plt.
  • Load CSV and print first 5 rows, dataset size, and overall survival rate.
  • Print missing values, then clean the data with fillna() and drop(), then print missing values again to confirm zeros.
  • The get_age_group function definition and the df["AgeGroup"] column creation with .apply().
  • Three groupby blocks printing survival rates by class, sex, and age group.
  • The matplotlib chart code: plt.bar(), the label loop, chart configuration, plt.savefig(), and plt.show() at the very end.

Secret mission

Build a Passenger Survival Profiler

You have survival statistics for groups of passengers. But what about one specific person? Build a function that takes any passenger's details and reports their survival odds based on the patterns you uncovered.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no ongoing costs or cloud resources to worry about. Decide whether to keep your project files, pause by deactivating your virtual environment, or delete everything entirely.

Resources you used:

  • titanic-analysis project folder (includes analyze.py, titanic.csv, and survival_by_class.png).
  • venv virtual environment inside the project folder (contains pandas and matplotlib).

Keep everything running

No action needed. Choose this if you plan to keep experimenting with the script or want to revisit the analysis later.

  • Your project files sit in the titanic-analysis folder and take up minimal disk space.
  • The venv virtual environment stays ready. Reactivate it any time to pick up where you left off.

Pause - I'll come back to this later

Deactivate your virtual environment to free up your terminal session. Your project files stay on disk.

  • Deactivate the virtual environment by running:
deactivate

The (venv) prefix disappears from your terminal prompt. When you want to resume, navigate back to the titanic-analysis folder and reactivate with .\venv\Scripts\Activate.

Delete - I don't want to use this again

Remove all project files, the virtual environment, and the downloaded dataset. This cannot be undone.

  • First, deactivate your virtual environment if it is still active:
deactivate
  • Navigate up one level so you are outside the project folder:
cd ..
  • Delete the entire titanic-analysis folder:

macOS

rm -rf titanic-analysis

Windows

rmdir /s /q titanic-analysis
  • Confirm the folder is gone by running:

macOS

ls titanic-analysis

Windows

dir titanic-analysis

You should see an error saying the path or directory does not exist. That confirms everything has been removed.

Nice Work!

Nice Work!

Nice work! You just built a complete Python data analysis script that answers a real question with real data: who was most likely to survive the Titanic?

You've learned how to:

  • Load real-world data with pandas read_csv(), explore it with head() and shape, and write Python variables, functions, f-strings, and loops to process a full dataset from scratch.
  • Discover that missing data silently corrupts analysis and fix it with fillna() and drop(), turning unreliable results into trustworthy insights.
  • Use groupby() to slice survival rates by class, sex, and age group, then create a bar chart with matplotlib and save it as a PNG file.
  • Secret Mission: Build a reusable survival_profile() function that profiles any passenger's survival odds based on the patterns you uncovered.

Ready to quiz yourself?