W3docs

Круговые диаграммы в Matplotlib

Создавайте и настраивайте круговые диаграммы в Python с Matplotlib: цвета, explode, donut-диаграммы, подписи, легенды и сохранение в файл.

Круговые диаграммы делят окружность на секторы, где угол каждого сектора пропорционален представляемому значению. Они лучше всего подходят, когда категорий немного (в идеале 2–6) и нужно показать, как каждая часть соотносится с целым — например, доля рынка по продуктам или распределение бюджета по отделам.

В этой главе рассматривается всё: от минимального первого графика до продвинутых техник, таких как donut-диаграммы, произвольное размещение подписей и сохранение готовых к публикации изображений. Во всех примерах используется matplotlib.pyplot — стандартный высокоуровневый API.

Установка и настройка

Если Matplotlib ещё не установлен, выполните эту команду в терминале:

pip install matplotlib

Каждый пример в этой главе начинается со следующего импорта:

import matplotlib.pyplot as plt

plt — стандартный псевдоним для matplotlib.pyplot. Он предоставляет такие функции, как plt.pie(), plt.title() и plt.show().

Создание базовой круговой диаграммы

plt.pie() — основная функция. Минимально она принимает последовательность числовых значений — пропорции вычисляются автоматически.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(values, labels=labels, autopct='%1.1f%%')
plt.title('Website Visitors by Device')
plt.show()

Ключевые используемые параметры:

ПараметрНазначение
valuesЧисловые данные; Matplotlib преобразует их в пропорции
labelsНазвания категорий, отображаемые рядом с каждым сектором
autopctСтрока форматирования для подписей процентов; '%1.1f%%' даёт 60.0%

По умолчанию диаграмма начинает рисовать секторы против часовой стрелки от позиции «3 часа». В следующем разделе объясняется, как это изменить.

Управление поворотом с помощью startangle

Установка startangle=90 поворачивает всю диаграмму так, что первый сектор начинается в позиции «12 часов» — наиболее естественная отправная точка для большинства читателей.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(
    values,
    labels=labels,
    autopct='%1.1f%%',
    startangle=90,
)
plt.title('Website Visitors by Device')
plt.show()

startangle принимает любой угол в градусах, отсчитываемый против часовой стрелки от положительной оси x. Значение 90 указывает прямо вверх.

Настройка цветов

Передайте список цветовых кодов в формате hex или именованных цветов в параметр colors. Список должен быть не короче, чем ваши данные.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']

plt.pie(
    values,
    labels=labels,
    colors=colors,
    autopct='%1.1f%%',
    startangle=90,
)
plt.title('Website Visitors by Device')
plt.show()

Также можно использовать любые встроенные цветовые карты Matplotlib. Например, чтобы получить три цвета из палитры tab10:

import matplotlib.pyplot as plt
import matplotlib.cm as cm

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

cmap = cm.get_cmap('tab10')
colors = [cmap(i) for i in range(len(values))]

plt.pie(values, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
plt.title('Website Visitors by Device')
plt.show()

Выдвижение сектора

Параметр explode смещает один или несколько секторов наружу, привлекая к ним внимание. Он принимает кортеж значений с плавающей точкой — по одному на каждый сектор. Значение 0.1 смещает сектор на 10 % радиуса диаграммы.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']
explode = (0.1, 0, 0)   # offset the first slice (Desktop) only

plt.pie(
    values,
    labels=labels,
    colors=colors,
    explode=explode,
    autopct='%1.1f%%',
    startangle=90,
    shadow=True,          # drop shadow for depth
)
plt.title('Website Visitors by Device')
plt.show()

Установка shadow=True добавляет едва заметную тень, которая ещё больше акцентирует внимание на выдвинутом секторе.

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

Используйте plt.title() для заголовка диаграммы и plt.legend() для отдельного блока легенды. Легенда полезна, когда текст подписей длинный или секторы слишком маленькие, чтобы подписать их напрямую.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']

plt.pie(
    values,
    labels=labels,
    colors=colors,
    autopct='%1.1f%%',
    startangle=90,
)
plt.title('Website Visitors by Device')
plt.legend(title='Device type', loc='lower right')
plt.show()

loc принимает стандартные строки позиционирования, такие как 'upper right', 'lower left' и 'center'. Также можно передать кортеж bbox_to_anchor для точного позиционирования в пикселях.

Управление расстоянием подписей

Два параметра определяют, как далеко подписи расположены от центра диаграммы:

  • labeldistance — расстояние подписи категории от центра, выраженное как доля радиуса. По умолчанию 1.1 (немного снаружи сектора).
  • pctdistance — расстояние подписи процента autopct от центра. По умолчанию 0.6 (внутри сектора).
import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(
    values,
    labels=labels,
    autopct='%1.1f%%',
    startangle=90,
    labeldistance=1.2,   # push category labels further out
    pctdistance=0.75,    # move percentages slightly outward from center
)
plt.title('Website Visitors by Device')
plt.show()

Увеличивайте pctdistance, когда секторы крупные и расположение по умолчанию выглядит загромождённым; уменьшайте, когда много маленьких секторов.

Создание donut-диаграммы

Donut-диаграмма — это круговая диаграмма с отверстием посередине. Используйте параметр wedgeprops, чтобы задать ширину кольца, выраженную как доля радиуса. Например, width=0.5 оставляет 50 % радиуса в качестве отверстия.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']

plt.pie(
    values,
    labels=labels,
    colors=colors,
    autopct='%1.1f%%',
    startangle=90,
    pctdistance=0.85,
    wedgeprops=dict(width=0.5),   # ring width = 50 % of radius
)
plt.title('Website Visitors by Device')
plt.show()

Donut-диаграммы популярны, поскольку пустой центр предоставляет место для общего числа или сводной метрики, которую можно добавить с помощью plt.text(0, 0, 'Total\n100', ha='center', va='center', fontsize=14).

Несколько круговых диаграмм рядом

Используйте plt.subplots(), чтобы разместить две или более круговых диаграммы на одном рисунке. Каждый вызов ax.pie() направлен на собственный объект осей.

import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

# --- Chart 1: this month ---
labels = ['Desktop', 'Mobile', 'Tablet']
values_this_month = [60, 30, 10]
ax1.pie(values_this_month, labels=labels, autopct='%1.1f%%', startangle=90)
ax1.set_title('This Month')

# --- Chart 2: last month ---
values_last_month = [70, 20, 10]
ax2.pie(values_last_month, labels=labels, autopct='%1.1f%%', startangle=90)
ax2.set_title('Last Month')

fig.suptitle('Website Visitors by Device', fontsize=14)
plt.tight_layout()
plt.show()

fig.suptitle() добавляет заголовок над всеми подграфиками. plt.tight_layout() предотвращает наложение подписей между диаграммами.

Сохранение круговой диаграммы в файл

Замените plt.show() на plt.savefig(), чтобы записать диаграмму на диск вместо отображения в окне. Это необходимо для скриптов, выполняемых на серверах без графического интерфейса, или для создания отчётных изображений.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=90)
plt.title('Website Visitors by Device')
plt.savefig('pie_chart.png', dpi=150, bbox_inches='tight')

Распространённые параметры savefig():

ПараметрЭффект
dpi=150Разрешение в точках на дюйм (72–300 для типичного использования)
bbox_inches='tight'Обрезает пустые поля вокруг рисунка
transparent=TrueСохраняет с прозрачным фоном
format='svg'Создаёт векторный SVG вместо растрового PNG

Распространённые ошибки

Значения, которые не составляют 100 в сумме. plt.pie() всегда нормализует значения так, чтобы секторы заполняли полную окружность. Если ваши значения представляют проценты и уже в сумме дают 100 — всё нормально. Если они представляют абсолютные числа — тоже нормально: Matplotlib делит каждое значение на общую сумму. Подпись autopct всегда показывает долю, а не исходное значение.

Нулевые или отрицательные значения. Matplotlib молча пропускает секторы с нулевым значением (они не создают видимого сектора). Отрицательные значения вызывают ValueError. Отфильтруйте их перед вызовом plt.pie().

Слишком много секторов. Круговые диаграммы становятся нечитаемыми при более чем 6–8 секторах. При большом числе категорий рассмотрите столбчатую диаграмму. Как вариант, объедините наименьшие категории в один сектор «Прочее».

Наложение подписей. Когда секторы маленькие, подписи перекрываются. Решения: увеличить labeldistance, использовать легенду вместо встроенных подписей (установите labels=None и вызовите plt.legend()), или использовать donut-диаграмму с бо́льшим пространством снаружи.

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

ПараметрТипПо умолчаниюНазначение
xsequenceЗначения данных
labelslistNoneНазвания категорий
colorslistcycleЦвета секторов
explodetupleNoneСмещение каждого сектора от центра
autopctstr / callableNoneФормат подписей процентов
pctdistancefloat0.6Расстояние подписи процента от центра
labeldistancefloat1.1Расстояние подписи категории от центра
startanglefloat0Начальный угол в градусах
shadowboolFalseТень
wedgepropsdictNoneСвойства каждого сегмента (например, width для donut)
counterclockboolTrueНаправление отрисовки секторов

Связанные темы

Was this page helpful?