Violin Plot в Python: мощный инструмент визуализации данных

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • профессионалы в области аналитики данных
  • студенты и начинающие аналитики, изучающие визуализацию данных
  • специалисты, работающие с Python и библиотеками для анализа данных

Визуализация данных — ключевой компонент аналитики, позволяющий превращать числовые массивы в интуитивно понятные образы. Среди множества инструментов Python особое место занимает Violin Plot — элегантное решение для детального анализа распределения данных. Этот график объединяет преимущества box plot и kernel density plot, позволяя одновременно оценить медиану, квартили, плотность распределения и выбросы. В 2025 году, когда объемы анализируемых данных продолжают расти экспоненциально, Violin Plot становится незаменимым инструментом для тех, кто стремится извлечь максимум информации из своих датасетов. 📊🎻

Хотите освоить передовые методы визуализации данных, включая Violin Plot и другие мощные инструменты? Курс «Аналитик данных» с нуля от Skypro — это ваш путь к профессиональному владению Python для анализа данных. Курс включает практические проекты с реальными данными, где вы научитесь создавать информативные визуализации, которые помогают принимать обоснованные решения. Инвестируйте в свои навыки сейчас, чтобы стать востребованным специалистом на рынке аналитики!

Что такое Violin Plot и его роль в анализе данных

Violin Plot (скрипичная диаграмма) представляет собой гибридный инструмент визуализации, сочетающий в себе элементы box plot (ящик с усами) и kernel density plot (график плотности вероятности). Название происходит от характерной формы графика, напоминающей скрипку или виолончель. 🎻

Основная ценность Violin Plot заключается в его способности одновременно отображать:

  • Полное распределение данных (через кривые плотности вероятности)
  • Медиану и квартили (через внутренние элементы "ящика")
  • Минимумы и максимумы (через "усы")
  • Выбросы (через отдельные точки)
  • Сравнительную плотность вероятности на разных участках распределения (через ширину "скрипки")

Алексей Петров, старший аналитик данных

Я столкнулся с необходимостью проанализировать время отклика API в различных географических регионах. Традиционные графики показывали только среднее значение и стандартное отклонение, что скрывало критические аномалии в данных. Внедрив Violin Plot в наш аналитический дашборд, мы обнаружили бимодальное распределение в некоторых регионах — это указывало на периодические проблемы с сетевой инфраструктурой. Благодаря этой находке мы оптимизировали маршрутизацию трафика и снизили время отклика на 37%. Скрипичные диаграммы позволили увидеть то, что оставалось невидимым на стандартных графиках, и это кардинально изменило наш подход к мониторингу производительности.

Преимущества Violin Plot по сравнению с другими методами визуализации:

Тип графика Отображение распределения Показ статистических метрик Сравнение групп Визуализация бимодальности
Violin Plot Полное + плотность Медиана, квартили, диапазон Отличное Явное
Box Plot Ограниченное Медиана, квартили, диапазон Хорошее Отсутствует
Histogram Дискретное Только визуально Ограниченное Видимое, но неточное
Density Plot Непрерывное Отсутствуют Среднее Видимое

Violin Plot становится особенно ценным в следующих ситуациях:

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

Создание базовых Violin Plot в Python с помощью Seaborn

Библиотека Seaborn делает создание Violin Plot в Python исключительно простым и гибким процессом. Рассмотрим основные способы построения скрипичных диаграмм с использованием различных наборов данных. 🐍

Для начала необходимо импортировать все необходимые библиотеки:

Python
Скопировать код
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# Установка стиля Seaborn
sns.set(style="whitegrid")

Базовый Violin Plot можно создать буквально одной строкой кода:

Python
Скопировать код
# Загрузка демонстрационного набора данных
tips = sns.load_dataset("tips")

# Создание базового Violin Plot
plt.figure(figsize=(10, 6))
sns.violinplot(x="day", y="total_bill", data=tips)
plt.title("Распределение счетов по дням недели")
plt.show()

Для сравнения нескольких категорий с дополнительной группировкой:

Python
Скопировать код
# Violin Plot с группировкой по полу
plt.figure(figsize=(12, 7))
sns.violinplot(x="day", y="total_bill", hue="sex", data=tips, split=True, palette="Set2")
plt.title("Распределение счетов по дням недели и полу клиентов")
plt.show()

Ключевые параметры функции violinplot в Seaborn:

Параметр Описание Возможные значения
data DataFrame с данными pandas.DataFrame
x, y Переменные для осей X и Y Имена столбцов в DataFrame
hue Группировка по категориям Имя категориального столбца
split Разделение "скрипок" для hue True/False
inner Представление внутри "скрипки" "box", "quartile", "point", "stick", None
scale Метод масштабирования ширины "area", "count", "width"
bw Сглаживание кривой плотности float или {"scott", "silverman"}

Для работы с собственными данными вы можете использовать DataFrame из любого источника:

Python
Скопировать код
# Пример с загрузкой данных из CSV
# df = pd.read_csv("path_to_your_data.csv")
# sns.violinplot(x="category_column", y="numeric_column", data=df)

# Пример с созданием синтетических данных
np.random.seed(42)
categories = ['A', 'B', 'C', 'D']
data = pd.DataFrame({
'category': np.random.choice(categories, 1000),
'value': np.concatenate([
np.random.normal(0, 1, 250), # Нормальное распределение для A
np.random.gamma(2, 2, 250), # Гамма-распределение для B
np.random.exponential(2, 250), # Экспоненциальное для C
np.concatenate([np.random.normal(-3, 1, 125), np.random.normal(3, 1, 125)]) # Бимодальное для D
])
})

plt.figure(figsize=(12, 7))
sns.violinplot(x="category", y="value", data=data, inner="quartile", palette="viridis")
plt.title("Violin Plot различных распределений")
plt.show()

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

Python
Скопировать код
# Сравнение Violin Plot с Box Plot
plt.figure(figsize=(15, 6))

plt.subplot(1, 2, 1)
sns.violinplot(x="category", y="value", data=data, inner="quartile")
plt.title("Violin Plot")

plt.subplot(1, 2, 2)
sns.boxplot(x="category", y="value", data=data)
plt.title("Box Plot")

plt.tight_layout()
plt.show()

Настройка и стилизация Violin Plot для презентаций

Профессиональная визуализация данных требует не только информативности, но и эстетического оформления, особенно для презентаций и публикаций. Seaborn предоставляет обширные возможности для настройки внешнего вида Violin Plot. 🎨

Начнем с базовой настройки стилей Seaborn:

Python
Скопировать код
# Установка стилей для презентационного качества
sns.set(style="whitegrid", context="talk", palette="pastel")
plt.figure(figsize=(12, 8))

# Создание основного графика с улучшенным стилем
vp = sns.violinplot(x="day", y="total_bill", data=tips, inner="quartile", 
palette="Set2", linewidth=1.5, saturation=0.8)

# Настройка осей и заголовков
plt.title("Распределение счетов по дням недели", fontsize=18, pad=20)
plt.xlabel("День недели", fontsize=14, labelpad=15)
plt.ylabel("Сумма счета ($)", fontsize=14, labelpad=15)

# Улучшение сетки для читаемости
plt.grid(axis='y', alpha=0.3, linestyle='--')

# Настройка тиков осей
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)

# Добавление аннотаций
medians = tips.groupby('day')['total_bill'].median().values
positions = range(len(medians))
for pos, median in zip(positions, medians):
plt.text(pos, median+1, f"${median:.2f}", horizontalalignment='center', 
size='medium', color='darkblue', weight='semibold')

plt.tight_layout()
plt.show()

Для создания многоуровневых Violin Plot с дополнительной информацией:

Python
Скопировать код
# Создание более сложного Violin Plot с подгруппами
plt.figure(figsize=(14, 8))

# Основной график с разделением по двум категориям
vp = sns.violinplot(x="day", y="total_bill", hue="time", data=tips, 
split=True, inner="quartile", palette={"Lunch": "#9b59b6", "Dinner": "#3498db"},
linewidth=1.2, cut=0)

# Добавление swarmplot для отображения фактических точек данных
sns.swarmplot(x="day", y="total_bill", hue="time", data=tips,
size=4, edgecolor="gray", linewidth=0.5, 
palette={"Lunch": "#d2b4de", "Dinner": "#aed6f1"}, 
dodge=True, alpha=0.7)

# Улучшение легенды
handles, labels = vp.get_legend_handles_labels()
plt.legend(handles[:2], labels[:2], title="Время приема пищи", 
loc="upper right", frameon=True, fontsize=12)

# Настройка осей и заголовков
plt.title("Распределение счетов по дням недели и времени приема пищи", 
fontsize=18, pad=20)
plt.xlabel("День недели", fontsize=14, labelpad=15)
plt.ylabel("Сумма счета ($)", fontsize=14, labelpad=15)

# Персонализация стиля графика
plt.grid(axis='y', alpha=0.3, linestyle='-.')
sns.despine(left=False, bottom=False)

plt.tight_layout()
plt.show()

Для создания высокоинформативных и стилизованных Violin Plot с добавлением статистической информации:

Python
Скопировать код
# Создание Violin Plot со статистическими элементами
plt.figure(figsize=(14, 10))

# Измененный формат основного графика
vp = sns.violinplot(x="day", y="total_bill", data=tips, inner=None, 
palette="YlGnBu", cut=0, width=0.8)

# Наложение boxplot для отображения статистических параметров
sns.boxplot(x="day", y="total_bill", data=tips, width=0.15, 
color="white", boxprops={"zorder": 2}, showfliers=False)

# Добавление фактических точек данных с jitter
sns.stripplot(x="day", y="total_bill", data=tips, size=3, 
color=".3", linewidth=0, alpha=0.4, jitter=True)

# Расчет и отображение статистик
for i, day in enumerate(tips['day'].unique()):
day_data = tips[tips['day'] == day]['total_bill']

# Среднее значение
plt.text(i, day_data.mean()+1, f"μ={day_data.mean():.2f}", 
horizontalalignment='center', size=11, color='darkgreen')

# Медиана уже показана в boxplot

# Стандартное отклонение
plt.text(i, day_data.max()+2, f"σ={day_data.std():.2f}", 
horizontalalignment='center', size=11, color='darkred')

# Улучшение внешнего вида
plt.title("Расширенный анализ распределения счетов по дням недели", 
fontsize=18, pad=20)
plt.xlabel("День недели", fontsize=14, labelpad=15)
plt.ylabel("Сумма счета ($)", fontsize=14, labelpad=15)

# Добавление подписи и пояснительного текста
plt.figtext(0.15, 0.01, "Примечание: μ – среднее значение, σ – стандартное отклонение", 
fontsize=10, style='italic')

plt.tight_layout(pad=2)
plt.show()

Дополнительные советы по стилизации для профессиональных презентаций:

  • Используйте согласованные цветовые схемы, соответствующие вашему бренду или теме презентации
  • Для научных публикаций выбирайте цветовые палитры, которые хорошо воспроизводятся при печати в оттенках серого
  • Добавляйте информативные подписи, пояснения и аннотации прямо на графике
  • Для сравнения нескольких категорий используйте цветовые градиенты вместо ярко контрастирующих цветов
  • Сохраняйте графики в векторных форматах (SVG, PDF) для презентаций высокого качества

Мария Соколова, руководитель отдела аналитики

Подготовка отчета для руководства о влиянии нового образовательного продукта на результаты студентов поставила перед нами серьезный вызов. У нас были данные по тестовым баллам, но стандартные столбчатые диаграммы средних значений не передавали полной картины. Решение пришло с Violin Plot — я создала сравнительную визуализацию, где контрольная и экспериментальная группы были представлены рядом. График наглядно показывал не только улучшение средних показателей, но и важнейший факт: новая методика особенно помогала отстающим студентам. Руководство, увидев эту визуализацию, моментально поняло ценность продукта и утвердило масштабное внедрение методики. Violin Plot превратил сложные статистические данные в четкую историю успеха, понятную даже нетехническим специалистам.

Сравнительный анализ распределений с Violin Plot

Одно из главных преимуществ Violin Plot — возможность наглядного сравнения распределений между различными группами данных. Это особенно полезно при проведении А/Б-тестирования, сравнении демографических групп или анализе изменений во времени. 📈

Рассмотрим методы эффективного построения сравнительных Violin Plot для выявления различий в распределениях:

Python
Скопировать код
# Загрузка датасета для демонстрации
diamonds = sns.load_dataset("diamonds")

# Подготовка данных для сравнения (выборка для ускорения визуализации)
diamonds_sample = diamonds.sample(n=3000, random_state=42)

# Сравнение распределения цен бриллиантов по качеству огранки
plt.figure(figsize=(14, 8))

# Основной Violin Plot
sns.violinplot(x="cut", y="price", data=diamonds_sample, 
palette="viridis", inner="quartile", 
order=["Fair", "Good", "Very Good", "Premium", "Ideal"])

# Настройка графика
plt.title("Распределение цен бриллиантов по качеству огранки", fontsize=16)
plt.xlabel("Качество огранки", fontsize=14)
plt.ylabel("Цена (USD)", fontsize=14)
plt.grid(axis='y', linestyle='--', alpha=0.7)

plt.show()

Для более детального сравнения можно добавить статистические тесты:

Python
Скопировать код
from scipy import stats
import numpy as np

# Функция для расчета и отображения результатов статистических тестов
def add_statistical_comparison(ax, data, x_var, y_var, pairs):
# Получение уникальных категорий и их позиций
categories = data[x_var].unique()
positions = dict(zip(categories, range(len(categories))))

# Высота для размещения скобок сравнения
y_max = data[y_var].max()

for i, (group1, group2) in enumerate(pairs):
# Получение данных для каждой группы
data1 = data[data[x_var] == group1][y_var]
data2 = data[data[x_var] == group2][y_var]

# Выполнение t-теста
t_stat, p_value = stats.ttest_ind(data1, data2, equal_var=False)

# Определение высоты для текущего сравнения
height = y_max + (i + 1) * (y_max * 0.05)

# Добавление скобки и p-value
x1, x2 = positions[group1], positions[group2]
plt.plot([x1, x1, x2, x2], [height-y_max*0.02, height, height, height-y_max*0.02], 
lw=1.5, c='black')

# Форматирование p-value для отображения
if p_value < 0.001:
p_text = "p < 0.001 ***"
elif p_value < 0.01:
p_text = f"p = {p_value:.3f} **"
elif p_value < 0.05:
p_text = f"p = {p_value:.3f} *"
else:
p_text = f"p = {p_value:.3f} (ns)"

plt.text((x1+x2)/2, height+y_max*0.01, p_text, ha='center', va='bottom', fontsize=12)

# Создание основного графика
plt.figure(figsize=(16, 10))
ax = sns.violinplot(x="cut", y="price", data=diamonds_sample, 
palette="viridis", inner="quartile", 
order=["Fair", "Good", "Very Good", "Premium", "Ideal"])

# Добавление статистических сравнений
pairs_to_compare = [("Fair", "Good"), ("Good", "Very Good"), 
("Very Good", "Premium"), ("Premium", "Ideal")]
add_statistical_comparison(ax, diamonds_sample, "cut", "price", pairs_to_compare)

# Настройка графика
plt.title("Статистическое сравнение цен бриллиантов по качеству огранки", fontsize=16)
plt.xlabel("Качество огранки", fontsize=14)
plt.ylabel("Цена (USD)", fontsize=14)
plt.ylim(0, diamonds_sample["price"].max() * 1.3) # Расширение для аннотаций
plt.grid(axis='y', linestyle='--', alpha=0.7)

# Пояснение к уровням значимости
plt.figtext(0.15, 0.01, "Уровни значимости: *** p<0.001, ** p<0.01, * p<0.05, ns – не значимо", 
fontsize=10, style='italic')

plt.tight_layout()
plt.show()

Для двумерного сравнения с дополнительной группировкой:

Python
Скопировать код
# Сравнение распределения цен по огранке и прозрачности
plt.figure(figsize=(18, 10))

# Фильтрация датасета для четкой визуализации
clarity_order = ["I1", "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF"]
cut_order = ["Fair", "Good", "Very Good", "Premium", "Ideal"]

# Создание основного графика с двумя факторами
sns.violinplot(x="clarity", y="price", hue="cut", data=diamonds_sample,
palette="YlOrBr", split=False, inner="quartile", 
order=clarity_order, hue_order=cut_order,
scale="width", gridsize=100)

# Улучшение читаемости визуализации
plt.title("Сравнительный анализ цен бриллиантов по прозрачности и качеству огранки", fontsize=16)
plt.xlabel("Прозрачность", fontsize=14)
plt.ylabel("Цена (USD)", fontsize=14)
plt.legend(title="Качество огранки", fontsize=12, title_fontsize=13)
plt.grid(axis='y', linestyle='--', alpha=0.4)

# Поворот подписей x-оси для лучшей читаемости
plt.xticks(rotation=45)

plt.tight_layout()
plt.show()

Ключевые методики для эффективного сравнительного анализа с помощью Violin Plot:

Тип сравнения Методика Когда использовать
Простое сравнение групп Базовый violinplot с упорядоченными категориями При сравнении до 7-8 групп с одномерными данными
Попарное сравнение со статистикой Violinplot + статистические тесты с аннотациями Для научных публикаций, требующих строгих статистических доказательств
Многофакторное сравнение Violinplot с параметром hue для группировки При анализе взаимодействия двух категориальных переменных
До/После сравнение Парные violinplot с разделенной осью При анализе изменений в эксперименте, А/Б-тестировании
Многомерное сравнение Матрица violinplot (FacetGrid) При необходимости сравнения по трем и более измерениям

Для создания матрицы сравнительных Violin Plot:

Python
Скопировать код
# Создание матрицы Violin Plot для многомерного сравнения
g = sns.FacetGrid(diamonds_sample, col="color", row="cut", 
margin_titles=True, height=3, aspect=1.2,
col_order=["D", "E", "F", "G", "H", "I", "J"],
row_order=["Ideal", "Premium", "Very Good", "Good", "Fair"])

# Определение функции построения для каждой ячейки
g.map(sns.violinplot, "clarity", "price", inner=None, order=clarity_order, 
palette="mako", cut=0, linewidth=1)

# Добавление индивидуальных точек для малых выборок
g.map(sns.stripplot, "clarity", "price", size=2, color=".3", 
linewidth=0, alpha=0.5, jitter=True)

# Настройка общих заголовков и подписей
g.set_axis_labels("Прозрачность", "Цена (USD)")
g.set_titles(col_template="Цвет: {col_name}", row_template="Огранка: {row_name}")
g.fig.suptitle("Многомерный анализ цен бриллиантов", fontsize=18)
g.fig.subplots_adjust(top=0.93)

# Поворот подписей оси x
for ax in g.axes.flat:
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)

plt.tight_layout()
plt.show()

Хотите определить, какое направление в аналитике лучше всего подходит для ваших навыков и интересов? Тест на профориентацию от Skypro поможет вам понять, стоит ли развиваться в области визуальной аналитики данных или ваши таланты лежат в другой сфере. Пройдите короткий онлайн-тест и получите персональные рекомендации по карьерному развитию, включая оценку ваших способностей к работе с такими инструментами как Violin Plot и другими методами визуализации данных.

Практические кейсы применения Violin Plot в исследованиях

Violin Plot находит широкое применение в различных областях исследований, от научных экспериментов до бизнес-аналитики. Рассмотрим несколько практических кейсов с реализацией в Python. 🔬

  1. Фармацевтические исследования: анализ эффективности препаратов
Python
Скопировать код
# Синтетические данные для демонстрации
np.random.seed(42)
drug_data = pd.DataFrame({
'Drug': np.repeat(['A', 'B', 'C', 'Placebo'], 50),
'Response': np.concatenate([
np.random.normal(30, 5, 50), # Препарат A
np.random.normal(25, 7, 50), # Препарат B
np.random.normal(40, 4, 50), # Препарат C
np.random.normal(20, 6, 50) # Плацебо
]),
'Age_Group': np.random.choice(['18-30', '31-45', '46-60', '60+'], 200)
})

# Создание расширенного Violin Plot
plt.figure(figsize=(14, 8))

# Основной график с цветовым кодированием по возрастным группам
ax = sns.violinplot(x="Drug", y="Response", hue="Age_Group", data=drug_data, 
palette="rocket", inner="quartile", split=False)

# Наложение точек данных для детального рассмотрения
sns.stripplot(x="Drug", y="Response", hue="Age_Group", data=drug_data, 
dodge=True, alpha=0.3, jitter=True, size=4, linewidth=1, 
palette="rocket")

# Устранение дублирования в легенде
handles, labels = ax.get_legend_handles_labels()
plt.legend(handles[:4], labels[:4], title="Возрастная группа", 
bbox_to_anchor=(1.05, 1), loc='upper left')

# Добавление статистической информации о средних значениях
for i, drug in enumerate(drug_data['Drug'].unique()):
mean_val = drug_data[drug_data['Drug'] == drug]['Response'].mean()
plt.text(i, mean_val + 2, f"μ = {mean_val:.1f}", 
ha='center', va='bottom', fontsize=12, weight='bold')

# Настройка внешнего вида
plt.title("Сравнение эффективности препаратов по возрастным группам", fontsize=16)
plt.xlabel("Препарат", fontsize=14)
plt.ylabel("Клинический ответ (единицы измерения)", fontsize=14)
plt.grid(axis='y', linestyle='--', alpha=0.5)

plt.tight_layout()
plt.show()

  1. Финансовый анализ: распределение доходности различных инвестиционных инструментов
Python
Скопировать код
# Синтетические данные о доходности инвестиций
np.random.seed(42)
investments = pd.DataFrame({
'Type': np.repeat(['Stocks', 'Bonds', 'Real_Estate', 'Crypto', 'Commodities'], 100),
'Return': np.concatenate([
np.random.normal(8, 15, 100), # Акции
np.random.normal(4, 3, 100), # Облигации
np.random.normal(6, 5, 100), # Недвижимость
np.concatenate([ # Криптовалюта (бимодальное распределение)
np.random.normal(20, 10, 50), 
np.random.normal(-10, 15, 50)
]),
np.random.normal(5, 8, 100) # Сырьевые товары
]),
'Year': np.random.choice(['2021', '2022', '2023', '2024', '2025'], 500)
})

# Расчет статистики рисков
risk_stats = investments.groupby('Type')['Return'].agg(['std', 'mean', 'median', 
lambda x: np.percentile(x, 10),
lambda x: np.percentile(x, 90)])
risk_stats.columns = ['Волатильность', 'Средняя доходность', 'Медиана', 'P10', 'P90']
risk_stats['Коэф. Шарпа'] = risk_stats['Средняя доходность'] / risk_stats['Волатильность']
risk_stats = risk_stats.sort_values('Коэф. Шарпа', ascending=False)

# Создание визуализации
plt.figure(figsize=(15, 10))

# Основной график
order = risk_stats.index
sns.violinplot(x="Type", y="Return", data=investments, inner="quartile", 
palette="Blues", order=order, cut=0)

# Добавление горизонтальной линии на уровне нулевой доходности
plt.axhline(y=0, color='red', linestyle='--', alpha=0.7)

# Аннотации с ключевыми рисковыми метриками
for i, typ in enumerate(order):
stats = risk_stats.loc[typ]
plt.annotate(f"Волат: {stats['Волатильность']:.1f}\nШарп: {stats['Коэф. Шарпа']:.2f}", 
xy=(i, stats['P90'] + 2), xytext=(i, stats['P90'] + 5),
ha='center', va='bottom', fontsize=10,
bbox=dict(boxstyle="round,pad=0.3", fc='white', ec="gray", alpha=0.8))

# Настройка внешнего вида
plt.title("Распределение доходности по типам инвестиций (2021-2025)", fontsize=16)
plt.xlabel("Тип инвестиций", fontsize=14)
plt.ylabel("Годовая доходность (%)", fontsize=14)
plt.grid(axis='y', linestyle='--', alpha=0.5)

# Улучшение читаемости оси x
plt.xticks([0, 1, 2, 3, 4], ['Акции', 'Облигации', 'Недвижимость', 
'Криптовалюта', 'Сырьевые товары'], rotation=0)

plt.tight_layout()
plt.show()

  1. Образовательная аналитика: анализ результатов студентов до и после внедрения новых методик обучения
Python
Скопировать код
# Синтетические данные об успеваемости
np.random.seed(42)
n_students = 200
student_data = pd.DataFrame({
'Student_ID': range(1, n_students + 1),
'Group': np.repeat(['Control', 'Experimental'], n_students // 2),
'Score_Before': np.concatenate([
np.random.normal(65, 15, n_students // 2), # Контрольная группа
np.random.normal(63, 14, n_students // 2) # Экспериментальная группа
]),
})

# Создание результатов после эксперимента с различным эффектом
control_after = student_data[student_data['Group'] == 'Control']['Score_Before'] + np.random.normal(5, 5, n_students // 2)
experimental_after = student_data[student_data['Group'] == 'Experimental']['Score_Before'] + np.random.normal(15, 8, n_students // 2)

student_data['Score_After'] = np.concatenate([control_after, experimental_after])

# Преобразование в "длинный" формат для визуализации
student_long = pd.melt(student_data, 
id_vars=['Student_ID', 'Group'],
value_vars=['Score_Before', 'Score_After'],
var_name='Time', value_name='Score')

student_long['Time'] = student_long['Time'].str.replace('Score_', '')

# Создание визуализации
plt.figure(figsize=(14, 9))

# Основной график
sns.violinplot(x="Group", y="Score", hue="Time", data=student_long, 
split=True, inner="quart", palette={"Before": "#3498db", "After": "#2ecc71"},
cut=0)

# Добавление линий, соединяющих средние значения
for group in ['Control', 'Experimental']:
group_data = student_long[student_long['Group'] == group]
mean_before = group_data[group_data['Time'] == 'Before']['Score'].mean()
mean_after = group_data[group_data['Time'] == 'After']['Score'].mean()

idx = 0 if group == 'Control' else 1
plt.plot([idx-0.2, idx+0.2], [mean_before, mean_after], color='black', 
linestyle='-', linewidth=2, marker='o', markersize=8)

# Добавление аннотации об улучшении
improvement = mean_after – mean_before
plt.annotate(f"+{improvement:.1f}", xy=(idx, (mean_before + mean_after)/2 + 2),
xytext=(idx + 0.35, (mean_before + mean_after)/2 + 2),
arrowprops=dict(arrowstyle='->'), fontsize=12, fontweight='bold',
color='darkgreen' if improvement > 10 else 'black')

# Настройка внешнего вида
plt.title("Влияние новой методики обучения на результаты студентов", fontsize=16)
plt.xlabel("Группа", fontsize=14)
plt.ylabel("Тестовый балл", fontsize=14)
plt.grid(axis='y', linestyle='--', alpha=0.5)
plt.ylim(20, 110)

# Добавление аннотации с описанием результатов
plt.figtext(0.15, 0.01, 
"Экспериментальная группа показала значительно более высокое улучшение показателей\n" +
"по сравнению с контрольной группой, что подтверждает эффективность новой методики.", 
fontsize=12)

plt.tight_layout()
plt.show()

Другие области практического применения Violin Plot:

  • Биомедицинские исследования: анализ экспрессии генов, сравнение биомаркеров между группами пациентов
  • Социологические исследования: визуализация распределения мнений по разным демографическим группам
  • Инженерный анализ: сравнение производительности различных систем или конфигураций
  • Экологические исследования: анализ распределения биологических показателей в разных экосистемах
  • Маркетинговые исследования: сравнение потребительских предпочтений между сегментами рынка
  • Спортивная аналитика: сравнение распределения показателей производительности спортсменов
  • Психологические исследования: анализ распределения результатов психологических тестов

Violin Plot — это не просто визуальный инструмент, а мощный способ глубокого понимания данных, который превосходит традиционные методы визуализации. Объединяя в себе лучшие качества box plot и плотностного распределения, скрипичные диаграммы позволяют аналитикам одновременно видеть центральные тенденции, вариативность, форму распределения и выбросы. Эта многогранность делает их незаменимыми при сравнительном анализе групп, выявлении неоднородностей в данных и поиске скрытых закономерностей. Владение этим инструментом — признак профессионального аналитика, способного извлечь максимум информации из своих данных.

Загрузка...