Skip to main content
Data Visualization
CHAPTER 06 Beginner

Bar Charts and Categorical Data

Updated: May 18, 2026
5 min read

# CHAPTER 6

Bar Charts and Categorical Data

1. Chapter Introduction

Bar charts are the workhorse of categorical comparison — which product sells most, which region performs best, which department has the highest headcount. This chapter covers all four bar chart types with production-quality styling.

2. Vertical Bar Chart

python
123456789101112131415161718192021222324252627
import matplotlib.pyplot as plt
import numpy as np

products = ['Laptop', 'Phone', 'Monitor', 'Tablet', 'Headphones', 'Camera']
sales    = [1850, 3200, 890, 1540, 2100, 620]

fig, ax = plt.subplots(figsize=(10, 6))

# Color bars by value rank
colors = ['#1565C0' if s == max(sales) else '#42A5F5' for s in sales]
bars = ax.bar(products, sales, color=colors, edgecolor='white', linewidth=0.5, width=0.6)

# Add value labels on top of bars
for bar, val in zip(bars, sales):
    ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 30,
            f'{val:,}', ha='center', va='bottom', fontsize=10, fontweight='bold')

ax.set_title('Product Sales Volume — Q4 2024', fontsize=14, fontweight='bold')
ax.set_xlabel('Product')
ax.set_ylabel('Units Sold')
ax.set_ylim(0, max(sales) * 1.15)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.grid(True, axis='y', alpha=0.3)
plt.tight_layout()
plt.savefig('vertical_bar.png', dpi=150)
plt.show()

3. Horizontal Bar Chart (Best for Long Labels)

python
1234567891011121314151617181920212223242526
regions = ['North America', 'Europe', 'Asia Pacific', 'Latin America',
           'Middle East', 'Africa', 'South Asia']
revenue = [2850000, 2100000, 1980000, 890000, 740000, 580000, 420000]

fig, ax = plt.subplots(figsize=(10, 6))

# Sort for easier reading
sorted_pairs = sorted(zip(revenue, regions))
revenue_s, regions_s = zip(*sorted_pairs)

colors = ['#1565C0' if r == max(revenue_s) else '#90CAF9' for r in revenue_s]
bars = ax.barh(regions_s, revenue_s, color=colors, edgecolor='white', height=0.6)

for bar, val in zip(bars, revenue_s):
    ax.text(val + 20000, bar.get_y() + bar.get_height()/2,
            f'${val/1e6:.2f}M', va='center', fontsize=10, fontweight='bold')

ax.set_title('Revenue by Region — 2024', fontsize=14, fontweight='bold')
ax.set_xlabel('Revenue (USD)')
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'${x/1e6:.1f}M'))
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.grid(True, axis='x', alpha=0.3)
plt.tight_layout()
plt.savefig('horizontal_bar.png', dpi=150)
plt.show()

4. Grouped Bar Chart

python
12345678910111213141516171819202122232425262728
categories = ['Electronics', 'Furniture', 'Clothing', 'Books', 'Sports']
q3_sales = [45000, 28000, 62000, 18000, 35000]
q4_sales = [72000, 31000, 89000, 22000, 41000]

x = np.arange(len(categories))
width = 0.35

fig, ax = plt.subplots(figsize=(11, 6))
bars1 = ax.bar(x - width/2, q3_sales, width, label='Q3 2024', color='#90CAF9', edgecolor='white')
bars2 = ax.bar(x + width/2, q4_sales, width, label='Q4 2024', color='#1565C0', edgecolor='white')

for bars in [bars1, bars2]:
    for bar in bars:
        ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 300,
                f'${bar.get_height()/1000:.0f}K', ha='center', va='bottom', fontsize=9)

ax.set_title('Quarterly Sales Comparison by Category', fontsize=14, fontweight='bold')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.set_ylabel('Sales ($)')
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'${x/1000:.0f}K'))
ax.legend()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.grid(True, axis='y', alpha=0.3)
plt.tight_layout()
plt.savefig('grouped_bar.png', dpi=150)
plt.show()

5. Stacked Bar Chart

python
12345678910111213141516171819202122232425
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
online   = [28000, 32000, 38000, 35000, 42000, 48000]
instore  = [45000, 41000, 47000, 44000, 50000, 52000]
wholesale= [12000, 14000, 16000, 15000, 18000, 20000]

fig, ax = plt.subplots(figsize=(11, 6))
ax.bar(months, online,    label='Online',    color='#1565C0', edgecolor='white')
ax.bar(months, instore,   label='In-Store',  color='#42A5F5', bottom=online, edgecolor='white')
ax.bar(months, wholesale, label='Wholesale', color='#90CAF9',
       bottom=[o+i for o,i in zip(online, instore)], edgecolor='white')

# Total labels
totals = [o+i+w for o,i,w in zip(online, instore, wholesale)]
for i, (month, total) in enumerate(zip(months, totals)):
    ax.text(i, total + 500, f'${total/1000:.0f}K', ha='center', fontsize=10, fontweight='bold')

ax.set_title('Monthly Sales by Channel', fontsize=14, fontweight='bold')
ax.set_ylabel('Revenue ($)')
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'${x/1000:.0f}K'))
ax.legend(loc='upper left')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
plt.savefig('stacked_bar.png', dpi=150)
plt.show()

6. Common Mistakes

  • Unsorted bars: Random order is hard to rank. Sort by value (descending) for immediate insight — the only exception is when category order is meaningful (months, weekdays).
  • Starting Y-axis above zero: Bar charts MUST start at zero — bar length encodes value. Truncating the Y-axis makes small differences look enormous.

7. MCQs

Question 1

Horizontal bar is preferred when?

Question 2

ax.barh() creates?

Question 3

Grouped bar chart compares?

Question 4

Stacked bar shows?

Question 5

Bar charts MUST start Y-axis at?

Question 6

bottom=online in stacked bar?

Question 7

Best practice for bar ordering?

Question 8

Adding value labels on bars uses?

Question 9

Bar width of 0.6 means bar occupies?

Question 10

edgecolor='white' in bar chart?

8. Interview Questions

  • Q: When would you use a stacked bar chart vs a grouped bar chart?
  • Q: Why should a bar chart's Y-axis always start at zero?

9. Summary

Four bar chart types: vertical (value comparison), horizontal (long labels), grouped (multi-category comparison), stacked (composition + total). Always start Y-axis at zero. Sort bars by value for instant ranking insight. Add value labels for precision. Use consistent colors for same categories across charts.

10. Next Chapter Recommendation

In Chapter 7: Pie Charts and Distribution Visualization, we learn when pie charts work, when they fail, and how donut charts improve readability.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·