Data Visualization in Python: Matplotlib and Seaborn, Line by Line
Data visualization is the practice of representing data visually — through charts, plots, and graphs — so patterns, trends, and outliers become easier to see than they would be in raw numbers alone, and Matplotlib and Seaborn are the two most common Python libraries for doing it.
Data visualization is the practice of representing data visually — through charts, plots, and graphs — so patterns, trends, and outliers become easier to see than they would be in raw numbers alone, and Matplotlib and Seaborn are the two most common Python libraries for doing it.
Why It's Used
Numbers in a table are precise, but they're hard for a human brain to absorb in bulk. Ask someone to look at a column of 500 numbers and tell you "how is this data shaped?" — they'll struggle. Show them a histogram of those same 500 numbers, and they'll answer in about two seconds.
Visualization isn't decoration — it's a shortcut for your brain's pattern-recognition system. It's how you'll spot outliers during EDA, understand relationships between features before modeling, and later, explain your results to other people who don't want to read a table of numbers.
Intuition
Think of raw data like a pile of ingredients dumped on a counter, and a chart like a plated meal. The ingredients are all there either way, but one of them is actually digestible at a glance. A chart takes the raw pile and arranges it — by size, by category, by relationship — so your eyes do the pattern-finding instead of your brain grinding through numbers one at a time.
Matplotlib is like a set of basic, reliable kitchen tools — a knife, a pan, a spoon. It can make almost anything, but you have to build it piece by piece yourself.
Seaborn is built on top of Matplotlib, and it's more like a set of pre-made molds — you hand it your data and tell it roughly what shape you want ("a histogram," "a boxplot grouped by category"), and it handles a lot of the styling and setup automatically, using good defaults so your chart looks clean without much fuss.
In practice, most people use both: Seaborn for quick, good-looking charts, and Matplotlib underneath for fine-tuning details Seaborn doesn't directly expose.
The Math
Visualization itself isn't a mathematical technique — it's a representation layer. But a few of the plot types below are worth understanding structurally, since "what a chart is actually showing" is often misunderstood.
Histogram: groups continuous values into equal-width ranges called bins, then counts how many values fall in each bin. If you have data points and choose bins spanning the range of your data, each bin's height is simply:
More bins show finer detail but can look noisy; fewer bins smooth things out but can hide structure. There's no single "correct" number of bins — it's a judgment call based on how much detail you want to see.
Boxplot: summarizes a distribution using five numbers, called a five-number summary:
Where (the first quartile) is the value below which 25% of the data falls, and (the third quartile) is the value below which 75% of the data falls. The "box" spans from to — this range is called the interquartile range (IQR):
Points beyond from the box edges are typically plotted individually as dots — a common, practical rule for flagging outliers visually.
Code
Matplotlib — The Basics
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([10, 25, 15, 30, 20])
# A basic line plot
plt.plot(x, y, marker="o", color="blue", label="Sales")
plt.title("Weekly Sales")
plt.xlabel("Week")
plt.ylabel("Sales (units)")
plt.legend()
plt.show()# A basic bar chart
categories = ["A", "B", "C", "D"]
values = [23, 45, 12, 38]
plt.bar(categories, values, color="skyblue")
plt.title("Sales by Category")
plt.xlabel("Category")
plt.ylabel("Total Sales")
plt.show()Seaborn — Cleaner Defaults, Less Setup
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
"category": ["A", "B", "C", "D", "A", "B", "C", "D"],
"value": [23, 45, 12, 38, 28, 41, 15, 35]
})
# Seaborn understands DataFrames directly — no need to manually extract columns
sns.barplot(data=df, x="category", y="value")
plt.title("Average Value by Category")
plt.show()# Histogram with Seaborn — one line, styled automatically
data = np.random.normal(loc=50, scale=10, size=500)
sns.histplot(data, bins=20, kde=True) # kde adds a smooth curve over the bars
plt.title("Distribution of Values")
plt.show()# Boxplot — great for spotting outliers and comparing groups
df2 = pd.DataFrame({
"department": ["Sales"]*5 + ["Engineering"]*5,
"salary": [45000, 47000, 46000, 51000, 95000, 70000, 72000, 68000, 74000, 71000]
})
sns.boxplot(data=df2, x="department", y="salary")
plt.title("Salary Spread by Department")
plt.show()# Scatterplot — showing the relationship between two numeric columns
df3 = pd.DataFrame({
"size_sqft": [750, 900, 1200, 1500, 1800, 2100],
"price_lakhs": [35, 55, 60, 85, 110, 130]
})
sns.scatterplot(data=df3, x="size_sqft", y="price_lakhs")
plt.title("House Size vs Price")
plt.show()Example / Output
Running the boxplot code on the salary example would produce a chart with two boxes side by side — one for Sales, one for Engineering. The Sales box would look tight and low, except for one dot floating well above it (the 95000 value), immediately flagging it as a likely outlier worth double-checking — exactly the kind of thing that's easy to miss in a raw table but impossible to miss in a boxplot.
The scatterplot would show points trending upward and to the right — as size_sqft increases, price_lakhs tends to increase too, visually confirming the kind of relationship a regression model would later try to capture mathematically.
Advantages and Disadvantages
| Advantages | Disadvantages | |
|---|---|---|
| Matplotlib | Full control over every detail of a chart; the foundation many other libraries build on | More code required for the same result; less attractive defaults out of the box |
| Seaborn | Clean, attractive charts with very little code; works directly with DataFrames | Less flexible for highly custom or unusual chart types; still relies on Matplotlib underneath for fine control |
Common Mistakes / Misunderstandings
- Choosing the wrong chart type for the data. A bar chart for continuous numeric distributions, or a line chart for unordered categories, usually confuses more than it clarifies. Match the chart to the question you're asking.
- Too many bins or too few bins in a histogram. Either extreme can hide the real shape of your data — it's worth trying a few different bin counts before settling.
- Forgetting axis labels and titles. A chart without labels might make sense to you right now, but it'll be meaningless to anyone else — including future-you, a week later.
- Reading too much into a small sample. A chart built from 5 data points can look convincing, but a visual pattern isn't the same as a real, statistically meaningful one.
Try This Yourself
Take the scatterplot code above and add hue="city" (after adding a city column with a few repeated category values) to sns.scatterplot(). Watch Seaborn automatically color-code the points by category — a small change that turns a two-variable chart into a three-variable one, with almost no extra code.
Want to go deeper? You can learn all of this properly, step by step, on our website.
Summary
- Data visualization turns raw numbers into shapes and patterns your brain can process almost instantly.
- Matplotlib gives full control but needs more manual setup; Seaborn builds on Matplotlib with cleaner, faster defaults.
- Histograms show distribution shape, boxplots show spread and outliers, and scatterplots show relationships between two variables.
- Choosing the right chart type for your question matters more than making a chart look impressive.
- Visualization is a core part of EDA, but it's also how you'll communicate results to others later on.
Common questions
What is the difference between Matplotlib and Seaborn?
Matplotlib is the foundational Python plotting library — it gives you full control but requires more code. Seaborn is built on top of Matplotlib and provides a higher-level interface with attractive default styles, especially for statistical plots and DataFrames.
When should I use a histogram vs a boxplot?
Use a histogram when you want to see the full shape of a distribution — the bins, peaks, and skew. Use a boxplot when you want a compact summary (median, quartiles, outliers) that's especially useful for comparing distributions across categories side by side.