Круговые диаграммы: pie()

Круговые диаграммы: pie() Matplotlib / Seaborn

Привет! Ты уже умеешь строить столбчатые диаграммы для сравнения категорий. Но что, если нужно показать, какую долю от целого составляет каждая часть? Например, распределение бюджета по статьям расходов или доли рынка разных компаний. Для этого идеально подходят круговые диаграммы.

В этой статье мы разберём:

  • Как строить круговые диаграммы с pie()
  • Настройка цветов, подписей и процентов
  • Выделение секторов (explode)
  • Кольцевые диаграммы (donut charts)
  • Когда использовать круговые диаграммы

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный Matplotlib (pip install matplotlib)
  • Базовое понимание графиков из предыдущих статей
  • Желание визуализировать пропорции

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

Основная часть

Простая круговая диаграмма

import matplotlib.pyplot as plt
import numpy as np

# Данные
categories = ['Продукты', 'Транспорт', 'Развлечения', 'Сбережения']
values = [45, 25, 20, 10]

# Создаём круговую диаграмму
plt.pie(values, labels=categories)
plt.title('Распределение расходов')
plt.show()

Совет: pie() принимает значения и подписи. Сумма значений может быть любой — Matplotlib автоматически пересчитает проценты.

Добавление процентов (autopct)

# Добавляем проценты на сектора
plt.pie(values, labels=categories, autopct='%1.1f%%')
plt.title('Распределение расходов с процентами')
plt.show()

Совет: autopct='%1.1f%%' показывает один знак после запятой. '%1.0f%%' — целые числа без запятой.

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

Цвета

# Список цветов
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']

plt.pie(values, labels=categories, autopct='%1.1f%%', colors=colors)
plt.title('Круговая диаграмма с цветами')
plt.show()

Тени и рамки

plt.pie(values, labels=categories, autopct='%1.1f%%', 
        shadow=True, wedgeprops={'edgecolor': 'black', 'linewidth': 1})
plt.title('Круговая диаграмма с тенью и рамкой')
plt.show()

Выделение секторов (explode)

# Выделяем сектор 'Сбережения' (выдвигаем на 0.1 радиуса)
explode = [0, 0, 0, 0.1]

plt.pie(values, labels=categories, autopct='%1.1f%%', explode=explode, shadow=True)
plt.title('Круговая диаграмма с выделенным сектором')
plt.show()

Совет: explode принимает список значений от 0 до 1, где 1 — полное выдвижение на радиус. Обычно используют 0.05–0.1.

Настройка размера и пропорций

# Делаем круг идеальным (equal aspect ratio)
plt.pie(values, labels=categories, autopct='%1.1f%%')
plt.axis('equal')  # Круг, а не эллипс
plt.title('Идеальный круг')
plt.show()
# Меняем размер фигуры
plt.figure(figsize=(8, 8))
plt.pie(values, labels=categories, autopct='%1.1f%%')
plt.title('Круговая диаграмма большого размера')
plt.show()

Совет: plt.axis('equal') делает круг идеальным (не эллипсом). Без него при нестандартных размерах фигуры круг может быть вытянут.

Кольцевая диаграмма (Donut Chart)

# Создаём кольцевую диаграмму
plt.figure(figsize=(8, 8))
plt.pie(values, labels=categories, autopct='%1.1f%%', 
        wedgeprops={'width': 0.4})  # Ширина кольца = 0.4
plt.title('Кольцевая диаграмма')
plt.show()

Совет: wedgeprops={'width': 0.4} делает кольцевую диаграмму. Чем меньше значение, тем тоньше кольцо.

Практический пример: распределение бюджета

import matplotlib.pyplot as plt

# Данные о расходах
categories = ['Продукты', 'Транспорт', 'Развлечения', 'Коммунальные', 'Сбережения', 'Одежда']
values = [35, 15, 20, 10, 12, 8]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F']
explode = (0, 0, 0.05, 0, 0.05, 0)  # Выделяем 'Развлечения' и 'Сбережения'

plt.figure(figsize=(10, 8))
plt.pie(values, labels=categories, autopct='%1.1f%%', 
        colors=colors, explode=explode, shadow=True,
        startangle=90, textprops={'fontsize': 12})
plt.title('Бюджет семьи за месяц', fontsize=16, fontweight='bold')
plt.axis('equal')
plt.tight_layout()
plt.show()

# Вывод процентов в консоль
total = sum(values)
print("=== Распределение бюджета ===")
for cat, val in zip(categories, values):
    print(f"{cat}: {val/total*100:.1f}%")

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

import matplotlib.pyplot as plt

# Данные за 2024 и 2025 годы
categories = ['Продукты', 'Транспорт', 'Развлечения', 'Сбережения']
values_2024 = [40, 25, 20, 15]
values_2025 = [35, 20, 25, 20]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#98D8C8']

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))

# 2024 год
ax1.pie(values_2024, labels=categories, autopct='%1.1f%%', colors=colors)
ax1.set_title('2024', fontsize=14, fontweight='bold')

# 2025 год
ax2.pie(values_2025, labels=categories, autopct='%1.1f%%', colors=colors)
ax2.set_title('2025', fontsize=14, fontweight='bold')

plt.suptitle('Сравнение структуры расходов', fontsize=16, fontweight='bold')
plt.tight_layout()
plt.show()

Круговая диаграмма с легендой

# Создаём диаграмму с легендой вместо подписей на секторах
plt.figure(figsize=(8, 8))
plt.pie(values, autopct='%1.1f%%', colors=colors, shadow=True)
plt.legend(categories, loc='upper right', fontsize=11)
plt.title('Расходы с легендой')
plt.axis('equal')
plt.show()

Совет: Легенда полезна, когда подписи слишком длинные или их много.

Когда использовать круговые диаграммы

Используй круговую диаграмму, когда:

  • Нужно показать доли от целого
  • Мало категорий (3–5, максимум 7)
  • Категории в сумме дают 100%
  • Важно показать относительные пропорции

Избегай круговой диаграммы, когда:

  • Много категорий (7+) — становится нечитаемой
  • Нужно сравнивать точные значения (лучше столбчатая диаграмма)
  • Категории не в сумме дают 100%

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

Полный пример: доли рынка

import matplotlib.pyplot as plt

# Данные о долях рынка смартфонов
companies = ['Samsung', 'Apple', 'Xiaomi', 'OPPO', 'Other']
market_share = [30, 25, 18, 12, 15]
colors = ['#2E86C1', '#1A5276', '#E74C3C', '#F39C12', '#95A5A6']
explode = (0.05, 0.05, 0, 0, 0)  # Выделяем Samsung и Apple

plt.figure(figsize=(10, 8))

# Строим диаграмму
wedges, texts, autotexts = plt.pie(
    market_share, 
    autopct='%1.1f%%',
    colors=colors,
    explode=explode,
    shadow=True,
    startangle=90,
    pctdistance=0.85,  # Расстояние процентов от центра
    wedgeprops={'edgecolor': 'white', 'linewidth': 2}
)

# Настройка текста
plt.setp(texts, size=12, fontweight='bold')
plt.setp(autotexts, size=12, fontweight='bold', color='white')

# Добавляем легенду
plt.legend(companies, loc='upper right', fontsize=12, framealpha=0.9)

plt.title('Доли рынка смартфонов в 2025 году', fontsize=16, fontweight='bold')
plt.axis('equal')
plt.tight_layout()
plt.show()

# Вывод данных
print("=== Рыночные доли ===")
for company, share in zip(companies, market_share):
    print(f"{company}: {share}%")

Задачи для закрепления

Задача 1. Построй круговую диаграмму для категорий ['A', 'B', 'C'] со значениями [30, 50, 20].

Задача 2. Добавь проценты с одним знаком после запятой.

Задача 3. Выдели сектор 'B' с помощью explode.

Задача 4. Сделай кольцевую диаграмму с шириной кольца 0.3.

Задача 5. Добавь тень и названия цветов для секторов.

Ответы:

Задача 1.

categories = ['A', 'B', 'C']
values = [30, 50, 20]
plt.pie(values, labels=categories)
plt.show()

Задача 2.

plt.pie(values, labels=categories, autopct='%1.1f%%')

Задача 3.

explode = [0, 0.1, 0]
plt.pie(values, labels=categories, autopct='%1.1f%%', explode=explode)

Задача 4.

plt.pie(values, labels=categories, autopct='%1.1f%%', wedgeprops={'width': 0.3})

Задача 5.

colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
plt.pie(values, labels=categories, autopct='%1.1f%%', colors=colors, shadow=True)

Нюансы и подводные камни

Порядок категорий

По умолчанию Matplotlib рисует секторы по часовой стрелке начиная с 12 часов. Изменить можно с помощью startangle:

plt.pie(values, startangle=90, labels=categories)  # Начинает с 3 часов

Слишком маленькие сектора

Сектора < 5% становятся нечитаемыми. Рассмотри группировку в «Другое».

autopct с функцией

autopct может принимать функцию для кастомного форматирования:

def make_autopct(values):
    def my_autopct(pct):
        total = sum(values)
        val = int(round(pct*total/100.0))
        return '{p:.1f}% ({v:d})'.format(p=pct, v=val)
    return my_autopct

plt.pie(values, autopct=make_autopct(values))

Частые ошибки и как их избежать

Ошибка 1: Слишком много категорий

# 10+ категорий — нечитаемо
plt.pie(values, labels=categories_10)

# 7 категорий максимум
# Используй столбчатую диаграмму для большого количества категорий
plt.bar(categories, values)

Ошибка 2: Плохая видимость процентов

# Проценты сливаются с секторами (особенно на светлых секторах)
plt.pie(values, autopct='%1.1f%%')

# Добавляем белый текст для тёмных секторов или настраиваем цвет
plt.pie(values, autopct='%1.1f%%', textprops={'color': 'white', 'fontweight': 'bold'})

Ошибка 3: Нет plt.axis(‘equal’)

# Круг вытянут в эллипс
plt.pie(values)
plt.show()

# Круг идеальный
plt.pie(values)
plt.axis('equal')
plt.show()

Шпаргалка

Что нужноКак пишется
Базовая диаграммаplt.pie(values, labels=categories)
Процентыautopct='%1.1f%%'
Цветаcolors=['#FF0000', '#00FF00']
Выделение сектораexplode=[0, 0.1, 0]
Теньshadow=True
Кольцевая диаграммаwedgeprops={'width': 0.4}
Начальный уголstartangle=90
Рамка секторовwedgeprops={'edgecolor': 'black', 'linewidth': 1}
Идеальный кругplt.axis('equal')
Легендаplt.legend(categories)
Размер фигурыplt.figure(figsize=(8, 8))

Заключение

Сегодня мы научились:

  • Строить круговые диаграммы с pie()
  • Настраивать цвета, подписи и проценты
  • Выделять сектора с explode
  • Создавать кольцевые диаграммы
  • Понимать, когда использовать круговые диаграммы

КВИЗ

Что дальше?

  • Следующая статья: «Ящики с усами: boxplot()»
Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×