Plotting Missing Values in Pandas – Visualizing NaNs Effectively 2026
Visualizing missing values is one of the best ways to understand their pattern and impact. In 2026, combining Pandas with Seaborn and Matplotlib allows you to create clear, insightful visualizations that reveal where and how missing data occurs in your dataset.
TL;DR — Best Visualization Methods
sns.heatmap(df.isna())– Missing value heatmap (most popular)- Bar plot of missing percentages per column
- Row-wise missing value distribution
1. Missing Values Heatmap (Most Recommended)
import pandas as pd
import seaborn as sns
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", parse_dates=["order_date"])
plt.figure(figsize=(12, 8))
sns.heatmap(
df.isna(),
cbar=False,
cmap="viridis",
yticklabels=False
)
plt.title("Missing Values Heatmap (White = Missing)")
plt.xlabel("Columns")
plt.ylabel("Rows")
plt.show()
2. Bar Plot – Missing Values Percentage per Column
missing_pct = df.isna().mean() * 100
plt.figure(figsize=(12, 6))
missing_pct.sort_values(ascending=False).plot(
kind="bar",
color="tomato",
edgecolor="black"
)
plt.title("Percentage of Missing Values by Column")
plt.ylabel("Missing Percentage (%)")
plt.xlabel("Column Name")
plt.xticks(rotation=45, ha="right")
plt.tight_layout()
plt.show()
3. Distribution of Missing Values per Row
row_missing = df.isna().sum(axis=1)
plt.figure(figsize=(10, 6))
row_missing.value_counts().sort_index().plot(
kind="bar",
color="steelblue"
)
plt.title("Number of Missing Values per Row")
plt.xlabel("Number of Missing Values in a Row")
plt.ylabel("Count of Rows")
plt.show()
4. Best Practices for Visualizing Missing Values in 2026
- Use a heatmap (
sns.heatmap(df.isna())) as your primary visualization — it shows the pattern clearly - Create a bar plot of missing percentages sorted from highest to lowest
- Visualize the distribution of missing values per row to spot problematic records
- Use a consistent color scheme (e.g., dark colors for present, bright for missing)
- Always include a clear title and proper labels
Why Visualise Missing Data
Counts tell you how much is missing, but a plot shows where. A bar chart of missing counts ranks the worst columns, and a heatmap of isna() shows whether gaps appear in blocks, for example all columns failing on the same days.
Patterns matter for the fix. Random gaps can often be filled, while blocks of gaps suggest a collection problem that filling would hide.
Worked Example: Bar Chart and Heatmap
Synthetic readings with a block of gaps are plotted two ways.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
rng = np.random.default_rng(0)
df = pd.DataFrame(rng.normal(size=(30, 4)), columns=["a", "b", "c", "d"])
df.loc[10:14, ["b", "c"]] = np.nan
df.loc[rng.choice(30, 3, replace=False), "d"] = np.nan
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
df.isna().sum().plot.bar(ax=axes[0], title="Missing per column", rot=0)
sns.heatmap(df.isna(), cbar=False, ax=axes[1])
axes[1].set_title("Missing pattern by row")
fig.tight_layout()
print(df.isna().sum().tolist())
The heatmap reveals that columns b and c fail together for rows 10 to 14, while gaps in d are scattered. That difference would be invisible in counts alone.
Practical Tips
For very large tables, sort rows by date or by group before drawing the heatmap, so related gaps line up, or plot a random sample of rows to keep the chart readable.
Common Mistakes
- Plotting only counts and missing block patterns.
- Using a colour bar that adds nothing for booleans.
- Plotting huge tables without sampling or sorting.
- Filling block gaps without investigating the cause.
Quick Summary
- Bar charts rank columns by missing count.
- Heatmaps of isna() show patterns.
- Block gaps hint at collection problems.
- Choose the fix after seeing the pattern.
Conclusion
Visualizing missing values is much more insightful than just counting them. In 2026, the combination of a missing value heatmap, percentage bar plot, and row-wise distribution gives you a complete understanding of missing data patterns in your dataset. These visualizations should be one of the first steps in your exploratory data analysis (EDA) process.
Next steps:
- Create a missing values heatmap and a percentage bar plot for one of your current datasets to understand the missing data pattern