Histograms in Pandas & Seaborn – Understanding Data Distribution 2026

Data Manipulation Mar 18, 2026

Histograms in Pandas & Seaborn – Understanding Data Distribution 2026

Histograms are one of the most important visualization tools in data manipulation. They help you understand the distribution, spread, central tendency, and outliers in your numerical data. In 2026, combining Pandas built-in histograms with Seaborn gives you both quick insights and publication-quality plots.

TL;DR — Best Ways to Create Histograms

  • df["column"].hist() – Quick Pandas histogram
  • df["column"].plot(kind="hist") – More customizable
  • sns.histplot() – Modern, beautiful histograms with Seaborn

1. Basic Histogram with Pandas

import pandas as pd
import matplotlib.pyplot as plt

# Create a small demo file so this example runs as-is
# (in your project, sales_data.csv is your real export)
import numpy as np
rng = np.random.default_rng(42)
n = 60
pd.DataFrame({
    "order_date": pd.date_range("2026-01-01", periods=n, freq="3D"),
    "customer_id": rng.integers(101, 121, n),
    "customer_name": rng.choice([" ana", "ben ", "chen", "dana"], n),
    "product_id": rng.integers(1, 9, n),
    "region": rng.choice(["North", "South", "East", "West"], n),
    "category": rng.choice(["Electronics", "Computers", "Books", "Home"], n),
    "payment_method": rng.choice(["card", "cash", "wallet"], n),
    "segment": rng.choice(["consumer", "business"], n),
    "quantity": rng.integers(1, 6, n),
    "amount": rng.uniform(50, 2500, n).round(2),
    "discount": rng.choice([0.0, 0.05, 0.1, 0.2], n),
}).assign(
    price=lambda d: (d["amount"] / d["quantity"]).round(2),
    profit=lambda d: (d["amount"] * rng.uniform(0.05, 0.3, n)).round(2),
).assign(
    ship_date=lambda d: d["order_date"] + pd.Timedelta(days=2),
    status=lambda d: np.where(d["amount"] > 2000, "priority", "standard"),
).to_csv("sales_data.csv", index=False)

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

# Quick histogram
df["amount"].hist(bins=30, figsize=(10, 6), alpha=0.7)
plt.title("Distribution of Sales Amount")
plt.xlabel("Amount")
plt.ylabel("Frequency")
plt.show()

2. Improved Histogram with Pandas .plot()

df["amount"].plot(
    kind="hist",
    bins=40,
    figsize=(10, 6),
    alpha=0.75,
    color="skyblue",
    edgecolor="black"
)
plt.title("Sales Amount Distribution - 2026")
plt.xlabel("Sales Amount")
plt.ylabel("Number of Transactions")
plt.grid(True, alpha=0.3)
plt.show()

3. Professional Histograms with Seaborn (Recommended in 2026)

import seaborn as sns

plt.figure(figsize=(10, 6))
sns.histplot(
    data=df,
    x="amount",
    bins=40,
    kde=True,                    # Add Kernel Density Estimate
    color="royalblue",
    alpha=0.7
)
plt.title("Distribution of Sales Amount with KDE")
plt.xlabel("Sales Amount")
plt.ylabel("Density")
plt.show()

4. Multiple Histograms for Comparison

plt.figure(figsize=(12, 6))
sns.histplot(
    data=df,
    x="amount",
    hue="region",           # Color by region
    bins=30,
    kde=True,
    alpha=0.6
)
plt.title("Sales Amount Distribution by Region")
plt.show()

Best Practices in 2026

  • Use bins=30 to bins=50 as a good starting point
  • Add kde=True in Seaborn to see the smooth distribution curve
  • Use hue parameter in Seaborn to compare distributions across categories
  • Always label axes and add a clear title
  • Check for skewness and outliers using histograms before further analysis

Reading a Histogram

A histogram splits a numeric column into bins and counts how many values fall into each one. Its shape tells you whether data is symmetric or skewed, whether there are several peaks, and whether outliers sit far from the rest.

The number of bins changes the picture. Too few bins hide structure and too many create noise. Try a few values, or let seaborn choose with bins="auto", and add a kernel density line with kde=True to see the overall shape.

Worked Example: Comparing Bin Choices

Synthetic delivery times are drawn with two bin settings so the effect is easy to see.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

rng = np.random.default_rng(42)
times = pd.Series(rng.gamma(shape=2.0, scale=10.0, size=500), name="minutes")
print(times.describe().round(1))

fig, axes = plt.subplots(1, 2, figsize=(10, 4))
times.plot.hist(bins=5, ax=axes[0], title="5 bins")
sns.histplot(times, bins="auto", kde=True, ax=axes[1])
axes[1].set_title("auto bins with KDE")
fig.tight_layout()

Gamma-shaped delivery times are right-skewed: most deliveries are quick but a long tail of slow ones pulls the mean above the median. Five bins barely show this, while automatic bins and a density line make the tail obvious.

Practical Tips

When comparing two groups, draw their histograms with the same bin edges, either on one axes with transparency or on shared-axis subplots. Otherwise differences in shape may come from the bins rather than the data.

Common Mistakes

  • Using a histogram for categorical data instead of a bar chart.
  • Accepting the default bins without checking alternatives.
  • Comparing groups with different bin edges.
  • Ignoring the summary statistics behind the shape.

Quick Summary

  • Histograms show the distribution of one numeric variable.
  • Bin count changes what you see.
  • kde=True adds a smooth density line.
  • Check describe() alongside the plot.

Conclusion

Histograms are essential for understanding the shape and distribution of your data. In 2026, start with Pandas .hist() or .plot(kind="hist") for quick exploration, then use Seaborn’s histplot() with kde=True for beautiful, insightful visualizations. Good histograms help you detect outliers, skewness, and patterns that guide your entire data manipulation and analysis process.

Next steps:

  • Create histograms for all numeric columns in your current dataset and analyze their distributions

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices