---
title: Data Visualization in Python: Matplotlib and Seaborn, Line by Line
source: https://app.sythra.ai/learn/machine-learning/data-visualization-python-matplotlib-seaborn
topic: Machine Learning
updated: 2026-08-28
publisher: Sythra (https://app.sythra.ai)
---

# 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.

_Source: [https://app.sythra.ai/learn/machine-learning/data-visualization-python-matplotlib-seaborn](https://app.sythra.ai/learn/machine-learning/data-visualization-python-matplotlib-seaborn) — free to read on Sythra._

## Key points

- Matplotlib gives full control over charts but requires more setup; Seaborn offers cleaner defaults with less code.
- Histograms reveal distribution shape; boxplots highlight spread and outliers; scatterplots show relationships.
- The IQR rule (1.5 × IQR beyond box edges) is how boxplots flag outlier candidates automatically.
- Always include axis labels and titles — a chart without context is almost useless to anyone else.

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 $n$ data points and choose $k$ bins spanning the range of your data, each bin's height is simply:

$$\text{bin height} = \text{count of } x_i \text{ falling in that bin's range}$$

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**:

$$\text{min}, \quad Q_1, \quad \text{median}, \quad Q_3, \quad \text{max}$$

Where $Q_1$ (the first quartile) is the value below which 25% of the data falls, and $Q_3$ (the third quartile) is the value below which 75% of the data falls. The "box" spans from $Q_1$ to $Q_3$ — this range is called the **interquartile range (IQR)**:

$$\text{IQR} = Q_3 - Q_1$$

Points beyond $1.5 \times \text{IQR}$ from the box edges are typically plotted individually as dots — a common, practical rule for flagging outliers visually.

## Code

### Matplotlib — The Basics

```python
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()
```

```python
# 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

```python
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()
```

```python
# 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()
```

```python
# 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()
```

```python
# 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.

## FAQ

### 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.

---

Written by Sythra — Learn machine learning by building. Practice this topic with Sythra's AI tutor: https://app.sythra.ai/pricing
