| name | data-visualization |
| description | Data visualization best practices covering chart selection, color theory, layout design, and accessibility. Use when choosing the right chart type for data, designing dashboards, creating infographics, improving existing visualizations, or building data-driven presentations. Triggers on tasks involving chart type selection, color palette design, dashboard layout, data storytelling, matplotlib/plotly/D3.js visualization code, or visual data communication. |
| metadata | {"version":"1.0.0"} |
Data Visualization Best Practices
A comprehensive guide for creating effective, accurate, and beautiful data visualizations — covering chart selection, color theory, layout design, accessibility, and common pitfalls.
When to Apply
- Choosing the right chart type for your data
- Designing dashboards or data reports
- Creating visualizations with matplotlib, plotly, D3.js, ECharts, etc.
- Improving existing visualizations for clarity or aesthetics
- Building data-driven presentations
- Designing accessible visualizations for diverse audiences
1. Chart Selection Guide
1.1 Choosing the Right Chart
| What You Want to Show | Best Chart Type | Alternatives |
|---|
| Comparison (categories) | Bar chart (horizontal) | Grouped bar, Bullet chart |
| Comparison (over time) | Line chart | Area chart, Slope chart |
| Composition (static) | Stacked bar chart | Pie chart (≤5 items), Treemap |
| Composition (over time) | Stacked area chart | 100% stacked bar |
| Distribution | Histogram | Box plot, Violin plot |
| Relationship (2 variables) | Scatter plot | Bubble chart, Heatmap |
| Relationship (3+ variables) | Scatter matrix | Parallel coordinates |
| Ranking | Horizontal bar chart | Lollipop chart, Ordered table |
| Deviation | Diverging bar chart | Waterfall chart |
| Flow / Process | Sankey diagram | Alluvial diagram |
| Geography | Choropleth map | Bubble map, Cartogram |
| Single metric | Big number + trend | Gauge, Bullet chart |
| Part-to-whole | Donut chart | Waffle chart, Treemap |
| Correlation | Scatter plot with trend line | Heatmap matrix |
1.2 When to Use (and Avoid) Common Charts
Bar Chart — The workhorse
- Use for: Comparing discrete categories, showing rankings
- Avoid: Too many categories (>20), continuous data
- Tip: Always start Y-axis at 0
Pie / Donut Chart — Use sparingly
- Use for: Showing part-to-whole with ≤5 categories
- Avoid: >5 slices, similar-sized slices, precise comparison
- Tip: Donut > Pie (center space for label), always include percentages
Line Chart — Time series default
- Use for: Showing trends over continuous time periods
- Avoid: Too many lines (>7), categorical X-axis
- Tip: Highlight the key line, gray out others
Scatter Plot — Relationship explorer
- Use for: Showing correlation between two continuous variables
- Avoid: Very large datasets (>10k points without aggregation)
- Tip: Add trend line, color by category, size by third variable
Heatmap — Density and patterns
- Use for: Showing concentration across two dimensions
- Avoid: Too many categories, non-sequential color scales
- Tip: Use perceptually uniform color maps (viridis, plasma)
2. Color Theory for Data Visualization
2.1 Color Palette Types
| Palette Type | Use Case | Examples |
|---|
| Sequential | Ordered data (low to high) | Viridis, Blues, Oranges |
| Diverging | Data with meaningful midpoint | RdBu, PiYG, BrBG |
| Qualitative | Categorical data (no order) | Set2, Paired, Tab10 |
| Highlight | Draw attention to one category | Gray base + one accent color |
2.2 Color Rules
- Use color meaningfully — Every color should encode information
- Limit palette — Maximum 7-10 distinct colors for categories
- Respect color blindness — ~8% of men are colorblind
- Use sequential palettes for ordered data — Never use rainbow
- One accent color — Gray for context, one color for focus
- Consistent mapping — Same category = same color across all charts
2.3 Color-Blind Safe Palettes
Safe sequential: viridis, plasma, inferno, magma, cividis
Safe diverging: RdBu (red-blue), PRGn (purple-green), BrBG (brown-green)
Safe qualitative: IBM Design, Okabe-Ito, Wong palette
# Wong palette (8 colors, colorblind-safe)
# Black: #000000
# Orange: #E69F00
# Sky Blue:#56B4E9
# Green: #009E73
# Yellow: #F0E442
# Blue: #0072B2
# Vermillion:#D55E00
# Purple: #CC79A7
2.4 The Highlight Technique
colors = ['#E69F00' if cat == 'Target' else '#CCCCCC' for cat in categories]
colors = ['#E69F00', '#56B4E9', '#009E73', '#F0E442', '#0072B2', '#D55E00']
3. Typography & Labeling
3.1 Label Hierarchy
| Level | Element | Font Size | Weight |
|---|
| 1 | Chart title | 16-20px | Bold |
| 2 | Axis labels | 12-14px | Medium |
| 3 | Tick labels | 10-12px | Regular |
| 4 | Annotations | 10-11px | Regular / Italic |
| 5 | Source / notes | 8-9px | Light / Italic |
3.2 Labeling Best Practices
- Always label axes — Include units (e.g., "Revenue ($M)")
- Direct labeling > Legends — Place labels near data points when possible
- Rotate labels only as last resort — Prefer horizontal text
- Avoid chart junk — Remove unnecessary gridlines, borders, backgrounds
- Use annotations to highlight key insights, not just data points
3.3 Number Formatting
Good: Bad:
$1.2M $1200000
45.2% 0.452
1,234 1234
2024-01 Jan, 2024 (inconsistent)
3.2x 320%
4. Dashboard Design
4.1 Dashboard Layout Principles
┌─────────────────────────────────────────────────┐
│ Title + Filters + Date Range │
├──────────┬──────────┬──────────┬────────────────┤
│ KPI #1 │ KPI #2 │ KPI #3 │ KPI #4 │
├──────────┴──────────┴──────────┴────────────────┤
│ │
│ Primary Chart (Largest) │
│ │
├──────────────────────┬──────────────────────────┤
│ Secondary Chart │ Secondary Chart │
├──────────────────────┴──────────────────────────┤
│ Data Table (Detail) │
└─────────────────────────────────────────────────┘
4.2 Dashboard Rules
- Top-left to bottom-right — Most important info first (F-pattern)
- KPIs at top — Big numbers with sparklines or trend indicators
- One primary chart — Takes up the most space, answers the main question
- Consistent filters — Apply to all charts on the dashboard
- Progressive disclosure — Summary → Detail (drill-down)
- Max 5-7 charts per dashboard — More = cognitive overload
- Responsive design — Adapt to different screen sizes
4.3 KPI Card Design
┌──────────────────────┐
│ Total Revenue │ ← Label (12px, gray)
│ │
│ $2,458,930 │ ← Value (32px, bold, dark)
│ ▲ 12.3% vs last mo. │ ← Change (12px, green/red)
│ ━━━━━━━━━━━━━━━━━ │ ← Sparkline (optional)
└──────────────────────┘
5. Accessibility
5.1 Accessibility Checklist
5.2 Accessible Pattern Examples
Bad: Red = bad, Green = good (only color encoding)
🟥 Failed 🟩 Passed 🟩 Passed 🟥 Failed
Good: Color + icon + text
✗ Failed ✓ Passed ✓ Passed ✗ Failed
(red) (green) (green) (red)
6. Common Visualization Mistakes
6.1 The Hall of Shame
| Mistake | Problem | Fix |
|---|
| Truncated Y-axis | Exaggerates differences | Start at 0 (for bar charts) |
| Dual Y-axis | Misleading correlation | Use two separate charts or normalize |
| 3D charts | Distorts perception | Always use 2D |
| Rainbow color scale | Not perceptually uniform | Use viridis or sequential palette |
| Too many categories | Unreadable | Group small categories as "Other" |
| Missing units | Ambiguous values | Always include units in axis labels |
| Pie chart with many slices | Hard to compare | Use bar chart instead |
| No title | Unclear purpose | Every chart needs a descriptive title |
| Decorative chart junk | Distracts from data | Remove unnecessary elements |
| Inconsistent scales | Misleading comparison | Use same scale across comparable charts |
6.2 The Truncated Y-Axis Problem
Bad (Y starts at 90): Good (Y starts at 0):
│ │
│ ██ │ ██
│ ██ ██ │ ██ ██
│ ██ ██ ██ │ ██ ██ ██
└──────────── └────────────
90 95 100 0 50 100
Looks like 3x difference! Shows true ~5% difference
6.3 When Dual Y-Axis is OK (Rarely)
Only acceptable when:
- Both axes measure the same unit
- There's a clear, documented reason
- Alternative (two charts) is significantly worse
- The relationship is genuinely meaningful, not spurious
7. Visualization Code Patterns
7.1 Matplotlib Best Practices (Python)
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
plt.rcParams.update({
'font.family': 'sans-serif',
'font.size': 11,
'axes.spines.top': False,
'axes.spines.right': False,
'figure.dpi': 150,
})
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.barh(categories, values, color='#0072B2', height=0.6)
ax.set_xlabel('Revenue ($M)', fontsize=12)
ax.set_title('Quarterly Revenue by Product', fontsize=16, fontweight='bold', pad=20)
ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f'${x/1e6:.1f}M'))
for bar, val in zip(bars, values):
ax.text(bar.get_width() + 0.5, bar.get_y() + bar.get_height()/2,
f'${val/1e6:.1f}M', va='center', fontsize=10)
ax.grid(axis='x', alpha=0.3, linestyle='--')
ax.set_xlim(0, max(values) * 1.15)
plt.tight_layout()
plt.savefig('chart.png', bbox_inches='tight', dpi=150)
7.2 Plotly Best Practices (Python)
import plotly.express as px
fig = px.bar(
df, x='category', y='value', color='segment',
color_discrete_sequence=['#0072B2', '#E69F00', '#009E73'],
title='Revenue by Category and Segment',
labels={'value': 'Revenue ($M)', 'category': 'Product Category'},
)
fig.update_layout(
font=dict(family='sans-serif', size=12),
title_font=dict(size=18),
plot_bgcolor='white',
legend=dict(orientation='h', yanchor='bottom', y=1.02),
margin=dict(t=80, b=60, l=60, r=40),
)
fig.update_xaxes(showgrid=False)
fig.update_yaxes(gridcolor='#E5E5E5', gridwidth=0.5)
fig.show()
8. Data Storytelling Framework
8.1 Structure
- Context — What is the question? Why does it matter?
- Data — What does the data show? (Visual evidence)
- Insight — What is the key finding? (Annotation)
- Action — What should we do about it? (Recommendation)
8.2 Annotation Best Practices
- Use callout boxes for key insights, not just data labels
- Highlight the "so what" — why this data point matters
- Use before/after comparisons for impact
- Add trend lines and reference lines for context
- Include a narrative title that states the finding
Bad title: "Sales by Month"
Good title: "Sales peaked in March (+35%) driven by new product launch"
9. Quick Reference Checklist