Нормальное распределение, также известное как Гауссово распределение или кривая Гаусса, является фундаментальным понятием в статистике и теории вероятностей. Визуализация этого распределения с помощью мощных инструментов, таких как Matplotlib, позволяет глубже понять данные и выявить закономерности.
Что такое нормальное распределение (Гауссово распределение)?
Нормальное распределение — это непрерывное распределение вероятностей, характеризующееся симметричной колоколообразной кривой. Большинство значений данных группируются вокруг центрального среднего значения (mu), а частота их появления убывает по мере удаления от среднего. Форма кривой определяется стандартным отклонением (sigma), которое измеряет разброс данных.
Зачем визуализировать нормальное распределение?
Визуализация нормального распределения помогает:
- Оценить соответствие данных: Проверить, насколько эмпирическое распределение данных соответствует теоретическому нормальному распределению.
- Сравнить распределения: Наглядно сопоставить параметры (среднее, стандартное отклонение) различных наборов данных.
- Обнаружить аномалии: Выявить выбросы или отклонения от ожидаемой формы распределения.
- Презентовать результаты: Эффективно донести выводы статистического анализа до аудитории.
Краткий обзор Matplotlib для визуализации данных
Matplotlib — это основная библиотека Python для создания статических, анимированных и интерактивных визуализаций. Она предоставляет объектно-ориентированный API для встраивания графиков в приложения с использованием стандартных инструментов GUI (например, Tkinter, wxPython, Qt или GTK). Matplotlib гибок и позволяет создавать широкий спектр графиков, от простых гистограмм до сложных трехмерных поверхностей.
Генерация данных для нормального распределения
Для построения графика нормального распределения сначала необходимо сгенерировать или получить набор данных, который следует этому распределению.
Использование NumPy для создания выборки данных с нормальным распределением
Библиотека NumPy предоставляет удобные функции для генерации случайных чисел из различных распределений, включая нормальное. Функция numpy.random.normal() идеально подходит для этой задачи.
import numpy as np
from numpy.typing import NDArray
def generate_normal_data(mu: float, sigma: float, size: int) -> NDArray[np.float64]:
"""Генерирует выборку данных из нормального распределения.
Args:
mu: Среднее значение (математическое ожидание) распределения.
sigma: Стандартное отклонение распределения.
size: Размер генерируемой выборки.
Returns:
Массив NumPy с данными, распределенными нормально.
"""
if sigma <= 0:
raise ValueError("Стандартное отклонение (sigma) должно быть положительным.")
if size <= 0:
raise ValueError("Размер выборки (size) должен быть положительным целым числом.")
data: NDArray[np.float64] = np.random.normal(loc=mu, scale=sigma, size=size)
return data
# Пример генерации данных
mean_value: float = 0.0
std_dev: float = 1.0
sample_size: int = 1000
normal_data: NDArray[np.float64] = generate_normal_data(mean_value, std_dev, sample_size)
# print(f"Сгенерировано {len(normal_data)} точек данных.")
# print(f"Первые 5 точек: {normal_data[:5]}")
Параметры нормального распределения: среднее (mu) и стандартное отклонение (sigma)
- Среднее (μ, mu): Определяет центр распределения. Это точка, вокруг которой группируются данные. В коде NumPy это параметр
loc. - Стандартное отклонение (σ, sigma): Определяет ширину или разброс кривой распределения. Большее значение
sigmaсоответствует более широкой и плоской кривой, меньшее — более узкой и высокой. В коде NumPy это параметрscale.
Построение нормального распределения с помощью Matplotlib
После генерации данных можно приступать к их визуализации с помощью Matplotlib.
Создание гистограммы для визуализации распределения данных
Гистограмма — это эффективный способ визуализировать распределение количественных данных. Она группирует значения в интервалы (бины) и показывает частоту попадания данных в каждый интервал.
import matplotlib.pyplot as plt
import numpy as np
from numpy.typing import NDArray
from typing import Optional
# Используем сгенерированные ранее данные 'normal_data'
# mean_value = 0.0
# std_dev = 1.0
# sample_size = 1000
# normal_data = np.random.normal(mean_value, std_dev, sample_size)
def plot_histogram(
data: NDArray[np.float64],
bins: int = 30,
title: str = 'Гистограмма нормального распределения',
xlabel: str = 'Значения',
ylabel: str = 'Частота'
) -> None:
"""Строит гистограмму для заданных данных.
Args:
data: Массив данных для построения гистограммы.
bins: Количество бинов (интервалов) гистограммы.
title: Заголовок графика.
xlabel: Метка оси X.
ylabel: Метка оси Y.
"""
plt.figure(figsize=(10, 6))
plt.hist(data, bins=bins, density=True, alpha=0.6, color='g') # density=True нормализует гистограмму
plt.title(title)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.grid(axis='y', alpha=0.75)
plt.show()
# plot_histogram(normal_data)
Настройка гистограммы: количество бинов, цвет и прозрачность
Параметры функции plt.hist() позволяют гибко настраивать внешний вид гистограммы:
bins: Определяет количество интервалов. Выбор оптимального числа бинов важен для корректного отображения формы распределения.color: Задает цвет столбцов гистограммы.alpha: Управляет прозрачностью цвета (от 0 до 1).density: ЕслиTrue, результат является значением функции плотности вероятности для каждого бина (т.е. площадь гистограммы равна 1). Это полезно для сравнения с теоретической кривой PDF.
Добавление кривой нормального распределения к гистограмме
Чтобы сравнить эмпирическое распределение (гистограмму) с теоретическим нормальным распределением, можно наложить на гистограмму кривую функции плотности вероятности (PDF).
Использование функции плотности вероятности (PDF) для построения кривой
Модуль scipy.stats содержит функцию norm.pdf(), которая вычисляет значения PDF для нормального распределения с заданными параметрами mu и sigma.
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from numpy.typing import NDArray
from typing import Tuple
# Используем сгенерированные ранее данные 'normal_data', 'mean_value', 'std_dev'
# mean_value = 0.0
# std_dev = 1.0
# sample_size = 1000
# normal_data = np.random.normal(mean_value, std_dev, sample_size)
def plot_histogram_with_pdf(
data: NDArray[np.float64],
mu: float,
sigma: float,
bins: int = 30,
title: str = 'Гистограмма и PDF нормального распределения',
xlabel: str = 'Значения',
ylabel: str = 'Плотность вероятности'
) -> Tuple[plt.Figure, plt.Axes]:
"""Строит гистограмму данных и накладывает кривую PDF нормального распределения.
Args:
data: Массив данных.
mu: Среднее значение для PDF.
sigma: Стандартное отклонение для PDF.
bins: Количество бинов гистограммы.
title: Заголовок графика.
xlabel: Метка оси X.
ylabel: Метка оси Y.
Returns:
Кортеж с объектами Figure и Axes Matplotlib.
"""
fig, ax = plt.subplots(figsize=(10, 6))
# Построение гистограммы (нормализованной)
ax.hist(data, bins=bins, density=True, alpha=0.6, color='skyblue', label='Гистограмма данных')
# Создание диапазона значений для оси X
xmin, xmax = ax.get_xlim()
x: NDArray[np.float64] = np.linspace(xmin, xmax, 100)
# Вычисление значений PDF
pdf_values: NDArray[np.float64] = norm.pdf(x, mu, sigma)
# Построение кривой PDF
ax.plot(x, pdf_values, 'k', linewidth=2, label='Кривая PDF (теоретическая)')
ax.set_title(title)
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
ax.legend()
ax.grid(axis='y', alpha=0.75)
# plt.show() # Отображение графика
return fig, ax
# fig, ax = plot_histogram_with_pdf(normal_data, mean_value, std_dev)
# plt.show()
Улучшение визуализации графика
Стандартные графики Matplotlib можно значительно улучшить для повышения читаемости и информативности.
Добавление заголовка и меток осей
Как показано в примерах выше, функции ax.set_title(), ax.set_xlabel(), ax.set_ylabel() используются для добавления соответствующих текстовых описаний к графику.
Настройка пределов осей для лучшей видимости
Иногда Matplotlib автоматически выбирает не самые удачные пределы для осей. Их можно настроить вручную с помощью ax.set_xlim() и ax.set_ylim().
# Пример настройки пределов оси X
# ax.set_xlim(-4, 4)
Добавление легенды для идентификации элементов графика
Когда на графике присутствует несколько элементов (например, гистограмма и кривая PDF), легенда помогает понять, что обозначает каждый из них. Легенда добавляется с помощью ax.legend(), при условии, что при построении элементов были указаны метки (label=...).
Применение стилей и цветовых схем Matplotlib
Matplotlib предлагает различные встроенные стили (plt.style.use()), которые меняют внешний вид графиков (цвета, шрифты, толщину линий и т.д.). Популярные стили включают ‘ggplot’, ‘seaborn-v0_8-darkgrid’, ‘fivethirtyeight’.
# Пример применения стиля
# plt.style.use('ggplot')
# fig, ax = plot_histogram_with_pdf(normal_data, mean_value, std_dev) # Перестроить график с новым стилем
# plt.show()
Примеры и продвинутые методы
Рассмотрим несколько более сложных сценариев использования.
Сравнение нескольких нормальных распределений на одном графике
Можно легко визуализировать несколько нормальных распределений на одном графике, чтобы сравнить их параметры.
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from numpy.typing import NDArray
def plot_multiple_pdfs(params: list[dict[str, float]], xmin: float = -5, xmax: float = 5) -> None:
"""Строит кривые PDF для нескольких нормальных распределений.
Args:
params: Список словарей, где каждый словарь содержит 'mu' и 'sigma'.
xmin: Минимальное значение оси X.
xmax: Максимальное значение оси X.
"""
plt.figure(figsize=(10, 6))
x: NDArray[np.float64] = np.linspace(xmin, xmax, 200)
for p in params:
mu = p.get('mu', 0.0)
sigma = p.get('sigma', 1.0)
label = f'μ={mu}, σ={sigma}'
pdf_values: NDArray[np.float64] = norm.pdf(x, mu, sigma)
plt.plot(x, pdf_values, linewidth=2, label=label)
plt.title('Сравнение нескольких нормальных распределений')
plt.xlabel('Значение')
plt.ylabel('Плотность вероятности')
plt.legend()
plt.grid(True, alpha=0.6)
plt.show()
# Параметры для сравнения
distributions_params: list[dict[str, float]] = [
{'mu': 0, 'sigma': 1},
{'mu': 0, 'sigma': 1.5},
{'mu': -1, 'sigma': 0.8}
]
# plot_multiple_pdfs(distributions_params)
Использование различных стилей линий и маркеров
При построении нескольких кривых или точек на одном графике полезно использовать разные стили линий (linestyle), цвета (color) и маркеры (marker) для их различения. Эти параметры передаются в функцию ax.plot().
# Пример стилей в ax.plot()
# ax.plot(x, pdf_values, color='red', linestyle='--', linewidth=2, label='PDF 1')
# ax.plot(x, another_pdf, color='blue', linestyle=':', linewidth=2, label='PDF 2')
Сохранение графика в файл
Готовый график можно сохранить в файл различных форматов (PNG, JPG, PDF, SVG) с помощью метода fig.savefig().
# Получаем объекты figure и axes из функции построения
# fig, ax = plot_histogram_with_pdf(normal_data, mean_value, std_dev)
# Сохранение графика
# file_path = 'normal_distribution_plot.png'
# fig.savefig(file_path, dpi=300, bbox_inches='tight') # dpi - разрешение, bbox_inches='tight' убирает лишние поля
# print(f"График сохранен в файл: {file_path}")
Эта статья предоставила обзор методов построения и настройки визуализаций нормального распределения с использованием Matplotlib и NumPy в Python. Освоив эти техники, вы сможете эффективно анализировать и представлять данные, подчиняющиеся этому важному статистическому закону.