0Pricing
Pandas & NumPy Academy · Lesson

Bar Charts and Histograms

Visualise categorical counts with ax.bar() and data distributions with ax.hist(), adjusting bin count and edge colour.

Bar Charts and Histograms is a free Pandas & NumPy Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Pandas & NumPy Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Bar Charts and Histograms

Bar charts display categorical data: one bar per category, with bar height proportional to a value. They answer 'how much does each category have?'. Histograms display the distribution of a continuous numeric variable: the data is binned into intervals and bar height shows the count or frequency in each bin. They answer 'how are these values distributed?'. Both use ax.bar() and ax.hist() respectively.

ax.bar() for Vertical Bar Charts

ax.bar(x, height) draws a vertical bar chart where x is a sequence of category positions (or labels) and height is the bar value. Key parameters: width (default 0.8, controls bar width relative to the gap), color, edgecolor, and align ('center' or 'edge'). Returns a list of Rectangle artist objects.

import matplotlib.pyplot as plt
import numpy as np

categories = ['East', 'West', 'North', 'South']
values = [420, 380, 310, 290]

fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(categories, values, color='steelblue', edgecolor='white', width=0.6)
ax.set_title('Regional Revenue')
ax.set_xlabel('Region')
ax.set_ylabel('Revenue (USD)')
# plt.show()
plt.close()

Customising Bar Appearance

A few customisations make bar charts significantly more readable: use a single accent colour for all bars (or an array of colours for per-bar distinction), add value labels above each bar with ax.bar_label(), control bar width to leave breathing room, and set ax.set_ylim(0, max * 1.15) to give labels space above the tallest bar.

fig, ax = plt.subplots(figsize=(7, 4))
bars = ax.bar(categories, values, color='steelblue', edgecolor='white', width=0.6)

# Add value labels above bars
ax.bar_label(bars, fmt='%d', padding=3, fontsize=10)

# Give space above bars for labels
ax.set_ylim(0, max(values) * 1.15)
ax.set_title('Regional Revenue')
plt.tight_layout()
plt.close()

Horizontal Bar Charts with ax.barh()

Use ax.barh(y, width) for horizontal bar charts. Horizontal bars are preferred when category labels are long (they read left-to-right naturally) or when there are many categories (they stack more compactly). All the same customisation parameters apply: height controls the bar thickness, and ax.barh_label() (or ax.bar_label()) adds text labels.

import pandas as pd
df = pd.DataFrame({'region': categories, 'revenue': values})
df_sorted = df.sort_values('revenue')

fig, ax = plt.subplots(figsize=(7, 4))
ax.barh(df_sorted['region'], df_sorted['revenue'],
        color='steelblue', edgecolor='white', height=0.5)
ax.set_title('Revenue by Region (Sorted)')
ax.set_xlabel('Revenue (USD)')
plt.tight_layout()
plt.close()

Grouped Bar Charts

To compare multiple groups side by side, create a grouped bar chart by offsetting bar positions manually. Calculate the centre positions for each group, then subtract or add a fixed offset for each sub-group. The total bar width plus the inter-group gap must equal 1.0 to keep bars non-overlapping. Setting ax.set_xticks() centres the tick labels between the grouped bars.

products = ['A', 'B', 'C']
q1 = [80, 120, 95]
q2 = [90, 110, 105]

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

fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(x - width/2, q1, width, label='Q1', color='steelblue')
ax.bar(x + width/2, q2, width, label='Q2', color='coral')

ax.set_xticks(x)
ax.set_xticklabels(products)
ax.legend()
ax.set_title('Q1 vs Q2 Sales by Product')
plt.close()

Stacked Bar Charts

Stacked bars show the composition of a total across multiple sub-groups. The second group's bars start where the first group's bars end, using the bottom parameter. Each subsequent layer's bottom is the cumulative sum of all previous layers. Stacked bars are useful for showing both the total and the contribution of each component simultaneously.

q1_arr = np.array(q1)
q2_arr = np.array(q2)

fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(products, q1_arr, label='Q1', color='steelblue')
ax.bar(products, q2_arr, bottom=q1_arr, label='Q2', color='coral')

ax.legend()
ax.set_title('Stacked Q1 + Q2 Sales by Product')
ax.set_ylabel('Total Sales')
plt.close()

ax.hist() for Histograms

ax.hist(data, bins) creates a histogram. The bins parameter controls how many equally-spaced intervals the data is divided into (default 10). You can also pass a list of bin edges for unequal intervals. Key parameters: density=True normalises the histogram to a probability density, edgecolor adds borders between bars, and color and alpha control appearance.

np.random.seed(42)
data = np.random.randn(500)  # 500 samples from standard normal

fig, ax = plt.subplots(figsize=(7, 4))
ax.hist(data, bins=30, color='steelblue', edgecolor='white', alpha=0.7)
ax.set_title('Distribution of Values')
ax.set_xlabel('Value')
ax.set_ylabel('Count')
plt.close()

Choosing the Number of Bins

The number of bins greatly affects how a histogram looks. Too few bins hide structure; too many bins create noisy spikes. Common heuristics: Sturges rule (≈ log2(n) + 1), Scott rule, or Freedman-Diaconis. Matplotlib supports these as strings: bins='auto', bins='scott', bins='fd'. For exploratory analysis, try a few values manually; for presentations, pick the bin count that best communicates the shape.

fig, axes = plt.subplots(1, 3, figsize=(12, 4))

for ax, b in zip(axes, [5, 30, 'auto']):
    ax.hist(data, bins=b, edgecolor='white', color='steelblue', alpha=0.7)
    ax.set_title(f'bins={b}')
    ax.set_xlabel('Value')

plt.tight_layout()
plt.close()

Overlapping Histograms for Comparison

To compare two distributions on the same axes, call ax.hist() twice with different data and colours. Use alpha=0.5 for both so the overlap is visible. Add labels and call ax.legend(). Using density=True normalises both histograms to the same scale when the sample sizes differ, making the shapes directly comparable.

group_a = np.random.randn(300)
group_b = np.random.randn(300) + 1.5  # shifted right

fig, ax = plt.subplots(figsize=(7, 4))
ax.hist(group_a, bins=25, alpha=0.5, color='steelblue', label='Group A', density=True)
ax.hist(group_b, bins=25, alpha=0.5, color='coral', label='Group B', density=True)
ax.legend()
ax.set_title('Distribution Comparison')
plt.close()

Plotting Pandas Series and DataFrames

Both .plot.bar() and .plot.hist() are available as DataFrame/Series methods and produce Matplotlib figures automatically. They accept an ax parameter to draw on an existing Axes. This is the quickest way to create bar charts from grouped Pandas data: compute the groupby aggregation, call .plot.bar() on the result, then customise the returned Axes.

import pandas as pd
import numpy as np

df_sales = pd.DataFrame({
    'region': ['East', 'West', 'North', 'South'],
    'revenue': [420, 380, 310, 290]
}).set_index('region')

fig, ax = plt.subplots(figsize=(7, 4))
df_sales['revenue'].plot.bar(ax=ax, color='steelblue', rot=0)
ax.set_title('Revenue by Region')
plt.tight_layout()
plt.close()

Choosing Bar vs Histogram

The choice between a bar chart and a histogram depends on your data type. Use a bar chart when your x-axis represents distinct, unordered categories (product names, regions, user segments) where the bars represent aggregated values for each category. Use a histogram when your x-axis is a continuous numeric variable and you want to show how values are distributed across a range. Mixing them up is a common visualisation error that misleads readers about data type.

# Bar chart: categorical x-axis (product names)
products = ['Widget', 'Gadget', 'Doohickey']
revenue = [500, 300, 200]
fig, ax = plt.subplots(figsize=(5, 3))
ax.bar(products, revenue, color='steelblue')
ax.set_title('Revenue per Product (Bar Chart)')
plt.close()

# Histogram: continuous x-axis (order sizes)
order_sizes = np.random.exponential(scale=50, size=300)
fig, ax = plt.subplots(figsize=(5, 3))
ax.hist(order_sizes, bins=20, color='coral', edgecolor='white')
ax.set_title('Distribution of Order Sizes (Histogram)')
plt.close()

Quick Check

Test your understanding of bar charts and histograms from this lesson.

Lesson Recap

In this lesson you learned: ax.bar() creates vertical bar charts and ax.barh() creates horizontal bar charts; bottom enables stacked bars; ax.hist() creates histograms with bin count controlled by bins; and density=True normalises histograms for fair comparison. Next up we add axis labels, titles, and save publication-quality figures.

Frequently asked questions

Is the “Bar Charts and Histograms” lesson free?

Yes — the full text of “Bar Charts and Histograms” is free to read here on the web, and the Pandas & NumPy Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Pandas & NumPy Academy course, upgrade to CoddyKit PRO.

What will I learn in “Bar Charts and Histograms”?

Visualise categorical counts with ax.bar() and data distributions with ax.hist(), adjusting bin count and edge colour. You practise Pandas & NumPy Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Pandas & NumPy Academy?

No prior experience is required. Pandas & NumPy Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Bar Charts and Histograms” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Pandas & NumPy Academy lesson?

Yes. Every Pandas & NumPy Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Figure and Axes Architecture
  2. Line and Scatter Plots
  3. Bar Charts and Histograms
  4. Labels, Titles, and Saving Figures
← Back to Pandas & NumPy Academy