How to Create a Bar Chart in Pandas: A Complete Guide to Data Visualization

The most convenient way to create a bar chart in pandas is using the df.plot.bar() method, which provides a high-level API that delegates rendering to Matplotlib or other configurable backends.

When working with the pandas-dev/pandas repository, you can create a bar chart in pandas through a unified plotting interface that abstracts away backend complexity. The library's architecture allows you to generate vertical bars, horizontal bars, stacked visualizations, and multi-subplot layouts using consistent syntax across different rendering engines.

Understanding the pandas Plotting Architecture

The PlotAccessor Class: Your Entry Point

All bar chart creation in pandas flows through the PlotAccessor class defined in pandas/plotting/_core.py. This accessor attaches to every DataFrame and Series via the .plot property. When you call df.plot.bar(), you are invoking PlotAccessor.bar(), which builds an argument dictionary and forwards it to PlotAccessor.__call__.

The __call__ method resolves the plot kind ( "bar" or "barh" ), validates parameters, and handles data selection logic for the x and y arguments before passing control to the active backend.

Backend Abstraction and Matplotlib Integration

The pandas plotting system decouples the API from rendering through a backend selection mechanism. The function _get_plot_backend in pandas/plotting/_core.py reads the global option pd.options.plotting.backend (defaulting to "pandas.plotting._matplotlib") and imports the corresponding module.

When creating a bar chart, the default Matplotlib backend in pandas/plotting/_matplotlib.py receives the prepared data and constructs matplotlib.axes.Axes objects. It then calls ax.bar() for vertical charts or ax.barh() for horizontal charts, applying pandas-specific styling and layout defaults.

How to Create a Bar Chart in Pandas: 6 Practical Methods

1. Simple Vertical Bar Chart

The most basic way to create a bar chart in pandas uses df.plot.bar() with explicit column mapping. In pandas/plotting/_core.py, the bar method sets kind='bar' and passes your x and y selections to the backend.

import pandas as pd

df = pd.DataFrame(
    {"category": ["A", "B", "C"], "value": [10, 30, 20]}
)
ax = df.plot.bar(x="category", y="value", rot=0, title="Simple Bar Chart")

This generates a single Axes with three bars labeled A, C, and B, using the default Matplotlib renderer.

2. Stacked Bar Chart for Multiple Series

To visualize part-to-whole relationships, set stacked=True. The PlotAccessor passes this flag to the Matplotlib backend, which adjusts the bottom parameter for successive ax.bar() calls.

df = pd.DataFrame(
    {
        "speed": [0.1, 17.5, 40, 48],
        "lifespan": [2, 8, 70, 1.5],
        "animal": ["snail", "pig", "elephant", "rabbit"]
    }
).set_index("animal")

df.plot.bar(stacked=True, title="Stacked Bar Chart")

Each animal displays a composite bar with speed and lifespan segments.

3. Horizontal Bar Chart with barh

For long category labels, use df.plot.barh(). This invokes the same PlotAccessor machinery but sets kind='barh', triggering ax.barh() in the Matplotlib backend.

df = pd.DataFrame(
    {"fruit": ["Apple", "Banana", "Cherry"], "count": [50, 30, 20]}
)
df.plot.barh(x="fruit", y="count", color="steelblue", title="Horizontal Bars")

Bars extend rightward, preventing label overlap.

4. Subplots for Multi-Column Data

Create separate axes for each column using subplots=True. The backend iterates over columns, generating an array of Axes objects arranged according to the layout parameter.

df = pd.DataFrame(
    {
        "2019": [5, 3, 6],
        "2020": [7, 2, 8],
        "region": ["North", "South", "West"]
    }
).set_index("region")

axes = df.plot.bar(subplots=True, layout=(1, 2), legend=False)

This produces two side-by-side subplots, one per year.

5. Custom Colors and Styling

Pass color mappings through the color parameter. The PlotAccessor validates these and passes them to the backend's color cycle logic.

df = pd.DataFrame(
    {"category": ["X", "Y", "Z"], "val1": [4, 7, 5], "val2": [3, 2, 6]}
).set_index("category")

df.plot.bar(color={"val1": "tomato", "val2": "teal"}, title="Colored Bars")

Individual series render in tomato red and teal.

6. Switching to Alternative Backends

Demonstrate backend abstraction by changing the global option. The _get_plot_backend function in pandas/plotting/_core.py dynamically imports the specified module.

pd.options.plotting.backend = "plotly"
df.plot.bar(x="category", y="value", title="Plotly Bar Chart")

The identical API now returns an interactive Plotly figure, proving the architecture's flexibility.

Key Source Files and Implementation Details

File Role in Bar Chart Creation Source Link
pandas/plotting/_core.py Defines PlotAccessor, the public API (df.plot.bar, df.plot.barh) and backend selection logic via _get_plot_backend view file
pandas/plotting/_matplotlib.py Default Matplotlib backend implementing ax.bar and ax.barh rendering view file
pandas/plotting/__init__.py Exposes the plot accessor on Series and DataFrame objects view file
pandas/_config.py Stores the plotting.backend option consulted by _get_plot_backend view file
pandas/plotting/_misc.py Utility functions for color handling and plot styling view file

These files collectively implement the concise, backend-agnostic workflow that makes creating bar charts in pandas straightforward.

Summary

  • Use df.plot.bar() or df.plot.barh() as the primary interface to create a bar chart in pandas, leveraging the PlotAccessor class in pandas/plotting/_core.py.
  • Backend abstraction allows switching between Matplotlib, Plotly, or other engines by setting pd.options.plotting.backend without changing visualization code.
  • Advanced layouts including stacked bars, horizontal orientation, subplots, and custom color mapping are supported through parameters passed to the accessor.
  • Implementation delegates actual rendering to the active backend (default Matplotlib in pandas/plotting/_matplotlib.py), which handles ax.bar and ax.barh calls.

Frequently Asked Questions

What is the difference between plot.bar() and plot.barh() in pandas?

plot.bar() creates vertical bars where categories appear on the x-axis and values on the y-axis, while plot.barh() creates horizontal bars with categories on the y-axis and values extending horizontally along the x-axis. According to the pandas source code in pandas/plotting/_core.py, both methods route through the same PlotAccessor class but set the kind parameter to "bar" or "barh" respectively, which the Matplotlib backend in pandas/plotting/_matplotlib.py interprets to call ax.bar() or ax.barh().

How do I customize colors when creating a bar chart in pandas?

You can customize colors by passing the color parameter to df.plot.bar(), which accepts a single color string, a list of colors, or a dictionary mapping column names to colors. The PlotAccessor validates these inputs in pandas/plotting/_core.py before forwarding them to the active backend. For example, df.plot.bar(color={"sales": "green", "profit": "gold"}) assigns specific colors to each series, with the Matplotlib backend applying these through its color cycle logic in pandas/plotting/_matplotlib.py.

Can I use pandas plotting without Matplotlib?

Yes, pandas supports multiple plotting backends that you can configure via pd.options.plotting.backend. While Matplotlib serves as the default backend defined in pandas/plotting/_matplotlib.py, you can switch to alternatives like Plotly, HoloViews, or other compatible libraries by setting the option to the appropriate module path. The _get_plot_backend function in pandas/plotting/_core.py dynamically imports the specified backend module, allowing you to use the same df.plot.bar() API regardless of the rendering engine underneath.

How do I create a stacked bar chart with pandas?

To create a stacked bar chart, call df.plot.bar(stacked=True), which instructs the Matplotlib backend to accumulate values vertically rather than displaying them side by side. According to the implementation in pandas/plotting/_matplotlib.py, this parameter adjusts the bottom argument for successive ax.bar() calls, layering each series on top of the previous one. This works for both vertical bars with plot.bar() and horizontal bars with plot.barh(), making it ideal for visualizing part-to-whole relationships across multiple categories.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →