W3docs

Столбчатые диаграммы Matplotlib в Python — полное руководство

Создавайте вертикальные, горизонтальные, сгруппированные и составные столбчатые диаграммы в Python с Matplotlib. Цвет, ширина, планки погрешностей.

Функции bar() и barh() библиотеки Matplotlib позволяют строить столбчатые диаграммы для сравнения величин по категориям. В этой главе рассматривается всё: от простейшей однорядной диаграммы до сгруппированных и составных макетов, а также практические параметры настройки, которые пригодятся в реальных проектах: цвета, ширина столбцов, оформление границ, планки погрешностей и сохранение результата в файл.

Перед началом убедитесь, что Matplotlib установлен:

pip install matplotlib

Если вы впервые знакомитесь с библиотекой, сначала прочитайте главы Введение в Matplotlib и Начало работы.

Что такое столбчатая диаграмма?

Столбчатая диаграмма использует прямоугольные столбцы, длина которых кодирует числовое значение, что позволяет легко сравнивать величины по дискретным категориям — например, ежемесячную выручку, население по странам или результаты тестов по предметам.

Используйте столбчатую диаграмму, когда:

  • Вы сравниваете одну метрику по категориям (простая столбчатая диаграмма).
  • Вы хотите показать, как общее значение разбивается на части (составная столбчатая диаграмма).
  • Вам нужно сравнить несколько метрик рядом для одних и тех же категорий (сгруппированная столбчатая диаграмма).
  • Метки категорий длинные и лучше читаются горизонтально (горизонтальная столбчатая диаграмма).

Создание базовой вертикальной столбчатой диаграммы

Функция plt.bar(x, height) принимает последовательность меток категорий (или числовых позиций) и соответствующую последовательность высот столбцов.

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(categories, values)

plt.title('Sample Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')

plt.tight_layout()
plt.show()

plt.tight_layout() предотвращает обрезку подписей осей — полезная привычка добавлять его перед каждым вызовом show() или savefig().

Настройка внешнего вида столбцов

Цвет

Передайте одно название цвета, шестнадцатеричную строку или список цветов для каждого столбца в параметр color:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

# One color for all bars
plt.bar(categories, values, color='steelblue')

plt.title('Steelblue Bars')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Чтобы окрасить каждый столбец по-разному, передайте список:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]
colors     = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6']

plt.bar(categories, values, color=colors)

plt.title('Multi-Color Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Ширина столбцов и цвет границы

По умолчанию width равна 0.8 (80 % расстояния между позициями делений). Уменьшите её для более лёгкого вида или увеличьте, чтобы заполнить больше пространства. edgecolor рисует контур вокруг каждого столбца:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(
    categories, values,
    width=0.5,
    color='cornflowerblue',
    edgecolor='navy',
    linewidth=1.2,
)

plt.title('Custom Width and Edge')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Добавление легенды

Передайте строку label в bar() и вызовите plt.legend():

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(categories, values, color='teal', label='2024 Sales')
plt.legend()

plt.title('Bar Chart with Legend')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Поворот подписей делений

Длинные названия категорий перекрываются — поверните их с помощью plt.xticks(rotation=...):

import matplotlib.pyplot as plt

months = ['January', 'February', 'March', 'April', 'May', 'June']
sales  = [120, 95, 140, 160, 130, 175]

plt.bar(months, sales, color='darkorange')
plt.xticks(rotation=45, ha='right')   # ha='right' aligns the labels nicely

plt.title('Monthly Sales')
plt.xlabel('Month')
plt.ylabel('Units Sold')
plt.tight_layout()
plt.show()

Горизонтальные столбчатые диаграммы

plt.barh(y, width) рисует столбцы, вытянутые по горизонтали. Это особенно удобно, когда метки категорий длинные — они отображаются на оси y с достаточным горизонтальным пространством.

import matplotlib.pyplot as plt

languages  = ['Python', 'JavaScript', 'Java', 'C#', 'TypeScript']
popularity = [30.3, 25.1, 17.8, 12.4, 9.6]

plt.barh(languages, popularity, color='mediumseagreen')

plt.title('Programming Language Popularity (%)')
plt.xlabel('Share (%)')
plt.ylabel('Language')
plt.tight_layout()
plt.show()

Совет: отсортируйте данные перед построением, чтобы наиболее популярная категория отображалась вверху:

import matplotlib.pyplot as plt

languages  = ['Python', 'JavaScript', 'Java', 'C#', 'TypeScript']
popularity = [30.3, 25.1, 17.8, 12.4, 9.6]

# Sort ascending so the highest bar ends up at the top after barh reversal
pairs      = sorted(zip(popularity, languages))
popularity_sorted, languages_sorted = zip(*pairs)

plt.barh(languages_sorted, popularity_sorted, color='mediumseagreen')

plt.title('Programming Language Popularity (sorted)')
plt.xlabel('Share (%)')
plt.tight_layout()
plt.show()

Сгруппированные столбчатые диаграммы

Сгруппированная (рядная) столбчатая диаграмма сравнивает два или более ряда для одного набора категорий. В Matplotlib нет специальной функции для этого — вы создаёте её, смещая позиции x каждого ряда с помощью NumPy:

import matplotlib.pyplot as plt
import numpy as np

categories = ['Q1', 'Q2', 'Q3', 'Q4']
sales_2023 = [120, 135, 150, 170]
sales_2024 = [140, 160, 145, 195]

x     = np.arange(len(categories))  # [0, 1, 2, 3]
width = 0.35                         # width of each individual bar

fig, ax = plt.subplots()

bars1 = ax.bar(x - width / 2, sales_2023, width, label='2023', color='steelblue')
bars2 = ax.bar(x + width / 2, sales_2024, width, label='2024', color='darkorange')

ax.set_title('Quarterly Sales Comparison')
ax.set_xlabel('Quarter')
ax.set_ylabel('Units Sold')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()

plt.tight_layout()
plt.show()

Ключевые моменты:

  • x - width / 2 сдвигает первый ряд влево; x + width / 2 сдвигает второй ряд вправо, так что столбцы располагаются рядом.
  • ax.set_xticks(x) и ax.set_xticklabels(categories) размещают метки категорий по центру каждой группы.
  • Объектно-ориентированный API (fig, ax = plt.subplots()) предпочтителен для сгруппированных диаграмм, поскольку даёт явный контроль над каждой осью.

Добавление подписей значений на столбцах

Вы можете аннотировать каждый столбец его значением с помощью ax.bar_label() (добавлено в Matplotlib 3.4):

import matplotlib.pyplot as plt
import numpy as np

categories = ['Q1', 'Q2', 'Q3', 'Q4']
sales_2023 = [120, 135, 150, 170]
sales_2024 = [140, 160, 145, 195]

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

fig, ax = plt.subplots()
bars1 = ax.bar(x - width / 2, sales_2023, width, label='2023', color='steelblue')
bars2 = ax.bar(x + width / 2, sales_2024, width, label='2024', color='darkorange')

ax.bar_label(bars1, padding=3)
ax.bar_label(bars2, padding=3)

ax.set_title('Quarterly Sales with Labels')
ax.set_xlabel('Quarter')
ax.set_ylabel('Units Sold')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()

plt.tight_layout()
plt.show()

Составные столбчатые диаграммы

Составная столбчатая диаграмма размещает ряды один поверх другого, показывая, как отдельные части вносят вклад в итог. Используйте параметр bottom, чтобы указать Matplotlib начальную точку каждого ряда:

import matplotlib.pyplot as plt
import numpy as np

categories = ['A', 'B', 'C', 'D', 'E']
series1    = [10, 24, 36, 40, 15]
series2    = [ 5, 12, 15, 20, 10]
series3    = [ 8,  6, 10, 12,  7]

x = np.arange(len(categories))

plt.bar(x, series1, label='Group 1', color='steelblue')
plt.bar(x, series2, label='Group 2', color='darkorange',
        bottom=series1)
plt.bar(x, series3, label='Group 3', color='seagreen',
        bottom=np.array(series1) + np.array(series2))

plt.xticks(x, categories)
plt.title('Stacked Bar Chart')
plt.xlabel('Category')
plt.ylabel('Total Value')
plt.legend()
plt.tight_layout()
plt.show()

Значение bottom для третьего ряда — это поэлементная сумма первых двух, поэтому каждый столбец начинается ровно там, где закончился предыдущий. Использование np.array() обеспечивает корректное сложение списков.

Планки погрешностей

Когда данные имеют неопределённость или вариабельность (например, стандартное отклонение при повторных измерениях), добавьте планки погрешностей с помощью параметра yerr:

import matplotlib.pyplot as plt
import numpy as np

categories    = ['Control', 'Treatment A', 'Treatment B', 'Treatment C']
means         = [5.2, 7.8, 6.1, 9.4]
std_devs      = [0.5, 0.8, 0.6, 1.1]

plt.bar(
    categories, means,
    yerr=std_devs,
    capsize=5,           # width of the error bar caps
    color='cornflowerblue',
    edgecolor='black',
    linewidth=0.8,
)

plt.title('Experimental Results with Error Bars')
plt.xlabel('Group')
plt.ylabel('Mean Value')
plt.tight_layout()
plt.show()

capsize управляет горизонтальными засечками в верхней и нижней части каждой планки погрешностей; значение 4–6 обычно хорошо читается.

Сохранение столбчатой диаграммы в файл

Используйте plt.savefig() вместо plt.show() (или вызовите её перед show()). Формат указывается через расширение файла:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(categories, values, color='steelblue')
plt.title('Saved Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()

# Save as PNG at 150 dpi
plt.savefig('bar_chart.png', dpi=150)

# Save as vector PDF (ideal for publications)
plt.savefig('bar_chart.pdf')

plt.show()

Распространённые форматы: png, pdf, svg, eps. Используйте svg или pdf, когда нужно масштабируемое изображение, готовое к печати.

Управление размером фигуры

По умолчанию Matplotlib создаёт фигуру размером 6,4 × 4,8 дюйма. Передайте figsize=(width, height) в plt.figure() или plt.subplots(), чтобы переопределить его:

import matplotlib.pyplot as plt

categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
values     = [80, 70, 95, 110, 130, 150, 160, 155, 120, 100, 85, 90]

fig, ax = plt.subplots(figsize=(12, 5))  # wider figure for 12 months
ax.bar(categories, values, color='tomato')
ax.set_title('Monthly Data')
ax.set_xlabel('Month')
ax.set_ylabel('Value')

plt.tight_layout()
plt.savefig('monthly_bar_chart.png', dpi=150)
plt.show()

Краткий справочник

ЗадачаКод
Вертикальная столбчатая диаграммаplt.bar(x, y)
Горизонтальная столбчатая диаграммаplt.barh(y, width)
Изменить цветplt.bar(x, y, color='steelblue')
Изменить ширинуplt.bar(x, y, width=0.5)
Составные столбцыplt.bar(x, y2, bottom=y1)
Планки погрешностейplt.bar(x, y, yerr=errors, capsize=5)
Добавить подписи значенийax.bar_label(bars, padding=3)
Повернуть подписи оси xplt.xticks(rotation=45, ha='right')
Сохранить в файлplt.savefig('file.png', dpi=150)

Связанные главы

Was this page helpful?