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

> Learn the most convenient way to create a bar chart in pandas using df.plot.bar() for effective data visualization. A complete guide for developers.

- Repository: [pandas/pandas](https://github.com/pandas-dev/pandas)
- Tags: tutorial
- Published: 2026-02-16

---

**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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/_core.py), the `bar` method sets `kind='bar'` and passes your `x` and `y` selections to the backend.

```python
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.

```python
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.

```python
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.

```python
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.

```python
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`](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/_core.py) dynamically imports the specified module.

```python
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`](https://github.com/pandas-dev/pandas/blob/main/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](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/_core.py) |
| [`pandas/plotting/_matplotlib.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/_matplotlib.py) | Default Matplotlib backend implementing `ax.bar` and `ax.barh` rendering | [view file](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/_matplotlib.py) |
| [`pandas/plotting/__init__.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/__init__.py) | Exposes the `plot` accessor on `Series` and `DataFrame` objects | [view file](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/__init__.py) |
| [`pandas/_config.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/_config.py) | Stores the `plotting.backend` option consulted by `_get_plot_backend` | [view file](https://github.com/pandas-dev/pandas/blob/main/pandas/_config.py) |
| [`pandas/plotting/_misc.py`](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/_misc.py) | Utility functions for color handling and plot styling | [view file](https://github.com/pandas-dev/pandas/blob/main/pandas/plotting/_misc.py) |

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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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`](https://github.com/pandas-dev/pandas/blob/main/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.