Day 3 — Data Visualization
matplotlib · CSV files · Bar charts · Scatter plots
⬇ Today's slides (PDF)Schedule
| Time | Activity |
|---|---|
| 0:00 – 0:45 | Lecture: why visualize data? matplotlib basics, reading CSV files |
| 0:45 – 1:30 | Guided: make a bar chart from a dataset |
| 1:30 – 1:40 | Break |
| 1:40 – 3:00 | Open project: explore your dataset, make multiple charts |
Download a Dataset
Pick one. If you scraped/fetched data yesterday you can use that too — ask your instructor how to load it.
Pokémon Stats NBA Players Top Movies CountriesSave the CSV file to the same folder as your Python script.
Install
pip install matplotlib pandas
Quick Reference — New Things Today
Reading a CSV with pandas
import pandas as pd # pd is the shorthand everyone uses for pandas
# read_csv() loads the file into a DataFrame — think of it like a spreadsheet in Python
df = pd.read_csv("pokemon.csv")
print(df.head()) # show the first 5 rows so you can see the structure
print(df.columns.tolist()) # list the column names exactly as they appear in the file
Accessing columns
# Get an entire column as a Python list using the column name in square brackets
names = df["Name"].tolist()
hp = df["HP"].tolist()
# Filter rows — keep only the rows where a condition is True
high_hp = df[df["HP"] > 80] # only Pokémon with HP greater than 80
print(high_hp[["Name", "HP"]]) # show just those two columns
Sorting
# sort_values() sorts the whole DataFrame by a column
# ascending=False means highest value first (descending order)
# .head(10) keeps only the first 10 rows after sorting
top10 = df.sort_values("Attack", ascending=False).head(10)
Making Charts
Bar Chart
plt.bar() takes two required arguments:
- First argument — x labels: a list of the text labels that appear along the bottom of the chart, one per bar. Here we use the Pokémon names.
- Second argument — heights: a list of numbers that determine how tall each bar is. The first label is paired with the first height, the second with the second, and so on — the two lists must be the same length.
- color: optional — sets the color of all bars. You can use color names like
"tomato","steelblue","gold", or hex codes like"#ff5733".
import pandas as pd
import matplotlib.pyplot as plt # plt is the standard shorthand everyone uses
df = pd.read_csv("pokemon.csv")
# Sort by Attack highest-first, then keep only the top 10 rows
top10 = df.sort_values("Attack", ascending=False).head(10)
plt.figure(figsize=(10, 5)) # create a figure: 10 inches wide, 5 inches tall
# plt.bar(x_labels, heights, color=...)
# top10["Name"] — list of Pokémon names, one label per bar (x-axis)
# top10["Attack"] — list of Attack values, one number per bar (bar height)
# The 1st name is paired with the 1st Attack value, 2nd with 2nd, etc.
plt.bar(top10["Name"], top10["Attack"], color="tomato")
plt.title("Top 10 Pokémon by Attack") # title displayed above the chart
plt.xlabel("Pokémon") # label for the horizontal axis
plt.ylabel("Attack") # label for the vertical axis
plt.xticks(rotation=45, ha="right") # rotate x labels 45° so they don't overlap
plt.tight_layout() # fix spacing so labels aren't cut off
plt.show() # open the chart window
Scatter Plot
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("pokemon.csv")
plt.figure(figsize=(8, 6))
# scatter() plots one dot per row — x position is Attack, y position is Defense
# alpha=0.5 makes dots 50% transparent so overlapping dots are still visible
plt.scatter(df["Attack"], df["Defense"], alpha=0.5, color="steelblue")
plt.title("Attack vs Defense")
plt.xlabel("Attack")
plt.ylabel("Defense")
plt.tight_layout()
plt.show()
Horizontal Bar Chart
plt.barh() works just like plt.bar() but the bars go sideways instead of up. The "h" stands for horizontal. The arguments swap roles:
- First argument — y labels: a list of labels that appear along the left side of the chart (the y-axis), one per bar. Long text like movie titles fit much better here than squeezed along the bottom.
- Second argument — widths: a list of numbers that determine how far each bar extends to the right. Larger number = longer bar.
- color: same as
plt.bar()— optional color for all bars.
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("movies.csv")
# Sort ascending=True (lowest first), then .tail(8) takes the LAST 8 rows — the highest values
# This makes the biggest bars appear at the TOP of the horizontal chart
top8 = df.sort_values("Gross_Billions", ascending=True).tail(8)
plt.figure(figsize=(8, 5))
# plt.barh(y_labels, widths, color=...)
# top8["Title"] — list of movie titles, one label per bar (y-axis, left side)
# top8["Gross_Billions"] — list of box office numbers, one per bar (bar length going right)
plt.barh(top8["Title"], top8["Gross_Billions"], color="gold")
plt.title("Top 8 Highest-Grossing Movies")
plt.xlabel("Box Office (Billions $)") # label on the horizontal axis (the numbers)
plt.tight_layout()
plt.show()
plt.savefig("my_chart.png") before plt.show() to save your chart as an image file you can take home.
Stretch Goals
- Add colors to each bar — use a list of colors like
["red", "blue", "green", ...] - Add value labels on top of each bar (look up
plt.text()) - Make a line chart — great for data that changes over time (movie gross by year)
- Make a pie chart with
plt.pie()— try Pokémon types - Plot two datasets on the same chart (e.g., Attack and Defense side by side)
- Save your chart as a PNG with
plt.savefig("chart.png") - Boss challenge: Use your Day 2 data — load the CSV you saved and visualize it
More Chart Options — Pick Any
Every chart follows the same recipe: get two things that line up (labels + numbers, or two number lists), hand them to a plotting function, add a title and axis labels, then plt.show(). Use any dataset — the ones above, or your own data from Day 2.
Starter — one clear chart
Pie Chart of Categories
Count how many Pokémon are each type (or movies each genre) and show the shares.
counts = df["Type"].value_counts() # how many of each type
plt.pie(counts, labels=counts.index, autopct="%1.0f%%") # autopct shows percentages
plt.title("Pokémon by Type")
plt.show()
Poll-the-Room Survey
Ask the class a question (favorite game, hours of sleep), type the answers into two lists, and bar-chart them. Personal data is the most fun to look at.
Standard — show a distribution or relationship
Histogram
Show how one number is spread out — NBA points per game, or country populations.
plt.hist(df["Points"], bins=10, color="steelblue") # bins = number of bars
plt.title("Distribution of Points")
plt.xlabel("Points per game")
plt.ylabel("How many players")
plt.show()
Word-Frequency Bar Chart
Count the most common words in a paragraph (or your Day 2 scraped text) and chart the top 10. Look up collections.Counter.
Boss Challenge — multiple views at once
Two-Dataset / Dual-Axis Comparison
Put two related measures on one chart — e.g. Attack and Defense as two bar series side by side, or two lines with a second y-axis (ax.twinx()).
Dashboard of Subplots
Use plt.subplots(2, 2) to draw four charts in one window — a mini dashboard of your dataset. Give each one its own title.