Рисуем гистограммы, столбчатые и круговые диаграммы

На этом занятии мы продолжим знакомство с разными типами двумерных графиков и увидим, как можно строить столбчатые и круговые диаграммы.

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

Иногда данные требуется сгруппировать по определенным диапазонам и подсчитать сколько значений попадает в тот или иной интервал. Для выполнения такой задачи хорошо подходят столбчатые диаграммы и довольно известный их вид – это гистограмма распределения случайной величины.

Давайте сгенерируем вектор из 500 случайных величин и выведем их в виде гистограммы, используя функцию hist():

import numpy as np
import matplotlib.pyplot as plt
 
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot()
 
y = np.random.normal(0, 2, 500)
ax.hist(y)
ax.grid()
 
plt.show()

На выходе получим следующее изображение распределения нормальной СВ:

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

ax.hist(y, 50)

Прежний интервал теперь разбит на 50 диапазонов, столбиков стало больше и они выглядят тоньше.

Функции bar() и barh()

Похожий график можно сформировать и с помощью функции bar. Ей на вход, в самом простом варианте, нужно передать список отметок для столбцов x и значения высот каждого столбца y:

bar(x, y)

Например, так:

x = [f'H{i+1}' for i in range(10)]
y = np.random.randint(1, 5, len(x))
ax.bar(x, y)

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

y = np.random.normal(0, 2, 500)
x = np.linspace(np.min(y), np.max(y), 10)

Затем, подсчитаем, сколько величин попало в соответствующий диапазон и выведем список bars с помощью функции bar():

bars = [len(y[np.bitwise_and(y >= x[i], y < x[i+1])]) for i in range(len(x)-1)]
ax.bar(range(len(x)-1), bars)

Как видите, у нас получилось изображение аналогичное гистограмме. Только пришлось предварительно подготовить данные, что не очень удобно. Поэтому, когда нужно вывести распределение величин по диапазонам, то проще использовать функцию hist().

Если нам нужно отображать столбики относительно оси ординат, то для этого существует функция barh(), которая работает аналогично функции bar():

ax.barh(range(len(x)-1), bars)

В итоге, график будет выглядеть, следующим образом:

Функции bar() и barh() содержат ряд полезных параметров:

Параметр

Описание

width

ширина столбцов (число или список)

bottom

начальное значение столбцов (по умолчанию 0)

align

выравнивание столбцов относительно риски: {'center',  'edge'} (по умолчанию 'center')

alpha

степень прозрачности (число от 0 до 1)

color

цвет столбцов

edgecolor

цвет границы

linewidth

толщина линии (вокруг столбца)

xerr, yerr

отображение величины погрешности (ошибки) для столбцов по горизонтали и по вертикали (число или список)

ecolor

цвет рисок линий погрешностей

log

True/False (включение/выключение логарифмического масштаба)

orientation

ориентация столбцов: {'vertical', 'horizontal'}

В качестве примера, воспользуемся несколькими параметрами из этой таблицы:

x = [f'H{i+1}' for i in range(10)]
y = np.random.randint(-20, 20, len(x))
ax.bar(x, y, width=0.5, linewidth=2, edgecolor='r', yerr=2, bottom=10)
ax.grid()

Увидим результат:

Благодаря использованию параметра width мы легко можем формировать групповые столбчатые диаграммы, следующим образом:

x = np.arange(10)
y1 = np.random.randint(3, 20, len(x))
y2 = np.random.randint(3, 20, len(x))
w = 0.3
ax.bar(x - w/2, y1, width=w)
ax.bar(x + w/2, y2, width=w)

Здесь правые столбцы сдвинуты вправо на половину своей толщины, а левые – влево на половину той же ширины. В итоге, получаем такое наглядное групповое изображение столбиков.

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

Иногда вместо столбцов нам нужно наглядно изобразить доли чего-либо в виде круговой диаграммы. Для этого используется функция pie(), например, следующим образом:

vals = [10, 40, 23, 30, 7]
labels = ['Toyota', 'BMW', 'Lexus', 'Audi', 'Lada']
ax.pie(vals, labels=labels)

Эта функция имеет ряд полезных параметров:

Параметр

Описание

labels

список подписей для долей

explode

список долей, выносимых из диаграммы

colors

цвета долей

autopct

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

pctdistance

расстояние от центра доли до текстовой метки

shadow

отображение тени у диаграммы

labeldistance

расстояние для текстовых метод долей (по умолчанию 1.1)

startangle

начальный угол поворота диаграммы (против часовой стрелки)

radius

радиус диаграммы

counterclock

порядок размещения долей на диаграмме (по часовой стрелки или против часовой) True/False

center

координата центра диаграммы (по умолчанию (0, 0))

frame

отображение рамки вокруг диаграммы (True/False)

wedgeprops

словарь дополнительных параметров (см. класс matplotlib.patches.Wedge)

Например, можно выполнить следующие манипуляции с круговой диаграммой, используя эти параметры:

vals = [10, 40, 23, 30, 7]
labels = ['Toyota', 'BMW', 'Lexus', 'Audi', 'Lada']
exp = (0.1, 0.2, 0, 0, 0)
ax.pie(vals, labels=labels, autopct='%.2f', explode=exp, shadow=True)

Получим следующее изображение:

Используя словарь wedgeprops, можно сформировать диаграмму с пустотой внутри:

ax.pie(vals, labels=labels, shadow=True, wedgeprops=dict(width=0.5))

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

Вот так, достаточно просто можно создавать гистограммы, столбчатые и круговые диаграммы.