Привет! Линейные графики хороши для показа трендов, но что, если нужно увидеть, как связаны две переменные? Или найти выбросы? Для этого есть точечные графики (scatter plots) — один из самых мощных инструментов визуализации данных.
В этой статье мы разберём:
- Что такое точечный график и зачем он нужен
- Как строить графики с помощью
scatter() - Настройка цвета, размера и прозрачности точек
- Использование цветовой шкалы для третьей переменной
- Сравнение
scatter()иplot()
- Что нужно знать перед началом
- Основная часть
- Простой точечный график
- Разница между plot() и scatter()
- Настройка внешнего вида точек
- Размер точек (s)
- Цвет точек (c)
- Прозрачность (alpha)
- Цвет контура (edgecolors)
- Цветовая шкала для третьей переменной
- Размер точек для четвёртой переменной
- Практический пример: корреляция между признаками
- Визуализация кластеров
- Точечный график с подписями точек
- Полный пример: анализ данных о жилье
- scatter() с непрозрачностью для больших данных
- Задачи для закрепления
- Нюансы и подводные камни
- Сравнение scatter() и plot() по производительности
- Цветовая шкала и значения
- Частые ошибки и как их избежать
- Ошибка 1: Неправильная размерность массивов
- Ошибка 2: Путаница между plot() и scatter()
- Ошибка 3: Забыл plt.colorbar() для цветовой шкалы
- Шпаргалка
- Заключение
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный Matplotlib (
pip install matplotlib) - Базовое понимание графиков из предыдущих статей
- Желание находить связи в данных
Совет: Точечные графики — лучший способ визуализации корреляции между двумя переменными. Они показывают, как изменение одной переменной влияет на другую.
Основная часть
Простой точечный график
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
# Данные
x = np.random.rand(50) * 10
y = np.random.rand(50) * 10
# Создаём точечный график
plt.scatter(x, y)
plt.title('Простой точечный график')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True, alpha=0.3)
plt.show()Совет:
scatter()отображает каждую пару значений (x, y) как отдельную точку. Это помогает увидеть скопления и пустоты в данных.
Разница между plot() и scatter()
plot() | scatter() |
|---|---|
| Соединяет точки линиями | Отображает отдельные точки |
| Каждая точка — одна пара | Каждая точка — одна пара |
| Не настраивается размер точек | Можно настраивать размер точек |
| Ограниченные возможности по цвету | Можно задавать цвет для каждой точки |
# Сравнение
x = np.linspace(0, 10, 20)
y = np.sin(x)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
# plot() — линии между точками
ax1.plot(x, y, marker='o')
ax1.set_title('plot() с маркерами')
ax1.grid(True, alpha=0.3)
# scatter() — только точки
ax2.scatter(x, y)
ax2.set_title('scatter()')
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()Совет:
scatter()лучше подходит для визуализации распределения данных.plot()— для трендов и временных рядов.
Настройка внешнего вида точек
Размер точек (s)
x = np.random.rand(30) * 10
y = np.random.rand(30) * 10
# Разные размеры точек
plt.scatter(x, y, s=100) # Большие
plt.scatter(x + 0.5, y + 0.5, s=20) # Маленькие
plt.title('Разный размер точек')
plt.show()Цвет точек (c)
plt.scatter(x, y, c='red')
plt.scatter(x + 0.5, y + 0.5, c='blue')
plt.title('Разный цвет точек')
plt.show()Прозрачность (alpha)
plt.scatter(x, y, alpha=0.5)
plt.title('Полупрозрачные точки')
plt.show()Цвет контура (edgecolors)
plt.scatter(x, y, s=100, facecolors='none', edgecolors='blue', linewidths=2)
plt.title('Точки с контуром')
plt.show()Совет: Прозрачность (
alpha) помогает видеть перекрывающиеся точки. Чем больше точек, тем меньше должна быть прозрачность.
Цветовая шкала для третьей переменной
Одна из самых мощных возможностей scatter() — кодировать третью переменную цветом:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
n = 100
x = np.random.rand(n) * 10
y = np.random.rand(n) * 10
colors = np.random.rand(n) * 100 # Третья переменная
plt.scatter(x, y, c=colors, cmap='viridis', s=50, alpha=0.7)
plt.colorbar(label='Третья переменная')
plt.title('Точечный график с цветовой шкалой')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True, alpha=0.3)
plt.show()Другие популярные цветовые схемы (cmap):
| Название | Описание |
|---|---|
'viridis' | От зелёного к синему (по умолчанию) |
'plasma' | От фиолетового к жёлтому |
'inferno' | От чёрного к жёлтому |
'coolwarm' | От синего к красному через белый |
'RdBu' | От красного к синему |
Совет: Цветовая шкала позволяет визуализировать до 4 измерений на одном графике: x, y, размер (s) и цвет (c).
Размер точек для четвёртой переменной
Можно использовать размер точек для ещё одной переменной:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
n = 50
x = np.random.rand(n) * 10
y = np.random.rand(n) * 10
colors = np.random.rand(n) * 100
sizes = np.random.rand(n) * 500 + 50
plt.scatter(x, y, c=colors, s=sizes, cmap='plasma', alpha=0.6)
plt.colorbar(label='Цветовая переменная')
plt.title('Цвет и размер кодируют две дополнительные переменные')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True, alpha=0.3)
plt.show()Совет: Использование размера и цвета на одном графике может сделать его перегруженным. Используй эту технику аккуратно.
Практический пример: корреляция между признаками
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
# Данные о продажах и рекламных затратах
ad_spend = np.random.randint(1, 50, 30) * 1000
sales = ad_spend * 2 + np.random.randint(-5000, 5000, 30)
plt.figure(figsize=(8, 6))
plt.scatter(ad_spend, sales, s=80, alpha=0.7, color='#2E86C1', edgecolors='black', linewidths=1)
# Добавляем линию тренда (позже в статье)
z = np.polyfit(ad_spend, sales, 1)
p = np.poly1d(z)
plt.plot(ad_spend, p(ad_spend), color='red', linewidth=2, label='Линия тренда')
plt.title('Зависимость продаж от рекламных затрат', fontsize=14, fontweight='bold')
plt.xlabel('Рекламные затраты (руб.)', fontsize=12)
plt.ylabel('Продажи (руб.)', fontsize=12)
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
# Выводим корреляцию
correlation = np.corrcoef(ad_spend, sales)[0, 1]
print(f"Коэффициент корреляции Пирсона: {correlation:.3f}")Совет: Корреляция близкая к 1 говорит о сильной положительной связи, близкая к -1 — об отрицательной. Близкая к 0 — связи нет.
Визуализация кластеров
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
# Создаём три кластера точек
cluster1 = np.random.randn(30, 2) + [2, 2]
cluster2 = np.random.randn(30, 2) + [8, 3]
cluster3 = np.random.randn(30, 2) + [5, 8]
plt.figure(figsize=(8, 6))
plt.scatter(cluster1[:, 0], cluster1[:, 1], label='Кластер 1', s=60, alpha=0.7)
plt.scatter(cluster2[:, 0], cluster2[:, 1], label='Кластер 2', s=60, alpha=0.7)
plt.scatter(cluster3[:, 0], cluster3[:, 1], label='Кластер 3', s=60, alpha=0.7)
plt.title('Визуализация трёх кластеров', fontsize=14, fontweight='bold')
plt.xlabel('Признак 1', fontsize=12)
plt.ylabel('Признак 2', fontsize=12)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()Точечный график с подписями точек
import matplotlib.pyplot as plt
# Данные с названиями
points = {
'A': (1, 10),
'B': (2, 15),
'C': (3, 8),
'D': (4, 20),
'E': (5, 12)
}
x = [points[p][0] for p in points]
y = [points[p][1] for p in points]
labels = list(points.keys())
plt.figure(figsize=(6, 5))
plt.scatter(x, y, s=80, color='blue')
# Добавляем подписи
for i, label in enumerate(labels):
plt.annotate(label, (x[i], y[i]), xytext=(5, 5), textcoords='offset points')
plt.title('Точечный график с подписями')
plt.grid(True, alpha=0.3)
plt.show()Совет: Подписи полезны, когда точек немного и важно показать названия объектов.
Полный пример: анализ данных о жилье
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
# Создаём данные о квартирах
n = 100
area = np.random.randint(30, 120, n)
price = area * 5000 + np.random.randint(-50000, 50000, n)
rooms = np.random.randint(1, 5, n)
floor = np.random.randint(1, 20, n)
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 1. Цена vs Площадь
axes[0, 0].scatter(area, price, s=60, alpha=0.6, color='blue')
axes[0, 0].set_title('Цена vs Площадь')
axes[0, 0].set_xlabel('Площадь (м²)')
axes[0, 0].set_ylabel('Цена (руб.)')
axes[0, 0].grid(True, alpha=0.3)
# 2. Цена vs Площадь (цвет = этаж)
scatter = axes[0, 1].scatter(area, price, c=floor, s=60, alpha=0.6, cmap='plasma')
axes[0, 1].set_title('Цена vs Площадь (цвет = этаж)')
axes[0, 1].set_xlabel('Площадь (м²)')
axes[0, 1].set_ylabel('Цена (руб.)')
axes[0, 1].grid(True, alpha=0.3)
plt.colorbar(scatter, ax=axes[0, 1], label='Этаж')
# 3. Цена vs Площадь (размер = комнаты)
scatter = axes[1, 0].scatter(area, price, c='green', s=rooms * 80, alpha=0.6)
axes[1, 0].set_title('Цена vs Площадь (размер = комнаты)')
axes[1, 0].set_xlabel('Площадь (м²)')
axes[1, 0].set_ylabel('Цена (руб.)')
axes[1, 0].grid(True, alpha=0.3)
# 4. Комнаты vs Площадь
axes[1, 1].scatter(rooms, area, s=60, alpha=0.6, color='purple')
axes[1, 1].set_title('Комнаты vs Площадь')
axes[1, 1].set_xlabel('Количество комнат')
axes[1, 1].set_ylabel('Площадь (м²)')
axes[1, 1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()scatter() с непрозрачностью для больших данных
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
# Генерируем 1000 точек
n = 1000
x = np.random.randn(n) * 10
y = np.random.randn(n) * 10
plt.figure(figsize=(8, 6))
plt.scatter(x, y, s=10, alpha=0.3)
plt.title('1000 точек с низкой непрозрачностью')
plt.grid(True, alpha=0.3)
plt.show()Совет: При большом количестве точек используй маленький размер и низкую прозрачность, чтобы избежать перекрытия.
Задачи для закрепления
Задача 1. Создай точечный график для случайных 30 точек.
Задача 2. Добавь на график синие точки размером 50.
Задача 3. Используй цветовую шкалу для третьей переменной.
Задача 4. Сделай точки полупрозрачными (alpha=0.5).
Задача 5. Построй scatter plot для визуализации корреляции между двумя переменными.
Ответы:
Задача 1.
x = np.random.rand(30) * 10
y = np.random.rand(30) * 10
plt.scatter(x, y)
plt.show()Задача 2.
plt.scatter(x, y, color='blue', s=50)Задача 3.
colors = np.random.rand(30) * 100
plt.scatter(x, y, c=colors, cmap='viridis')
plt.colorbar()
plt.show()Задача 4.
plt.scatter(x, y, alpha=0.5)Задача 5.
x = np.random.rand(50) * 10
y = x * 2 + np.random.randn(50) * 2
plt.scatter(x, y)
plt.show()Нюансы и подводные камни
Сравнение scatter() и plot() по производительности
scatter() может быть медленнее для очень большого количества точек (более 10000). В таких случаях используй plot() с маркерами:
# Для 10000+ точек
plt.plot(x, y, 'o', markersize=3, alpha=0.5)Цветовая шкала и значения
Цветовая шкала автоматически подстраивается под диапазон значений c. Если нужно зафиксировать диапазон, используй vmin и vmax:
plt.scatter(x, y, c=values, vmin=0, vmax=100, cmap='viridis')Частые ошибки и как их избежать
Ошибка 1: Неправильная размерность массивов
# Ошибка: x и y разной длины
plt.scatter([1, 2, 3], [1, 2])
# Правильно: одинаковые длины
plt.scatter([1, 2, 3], [1, 2, 3])Ошибка 2: Путаница между plot() и scatter()
# plot() соединяет точки линиями
plt.plot(x, y)
# scatter() показывает точки
plt.scatter(x, y)Ошибка 3: Забыл plt.colorbar() для цветовой шкалы
# Цветовая шкала не отображается
plt.scatter(x, y, c=colors)
# Добавляем шкалу
plt.scatter(x, y, c=colors)
plt.colorbar()Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Базовый scatter | plt.scatter(x, y) |
| Размер точек | s=50 |
| Цвет точек | c='red' |
| Прозрачность | alpha=0.5 |
| Цветовая шкала | cmap='viridis' и plt.colorbar() |
| Контур точек | edgecolors='black', linewidths=1 |
| Пустые точки | facecolors='none' |
| Фиксированный диапазон цветов | vmin=0, vmax=100 |
Заключение
Сегодня мы научились:
- Строить точечные графики с помощью
scatter() - Настраивать цвет, размер и прозрачность точек
- Использовать цветовую шкалу для третьей переменной
- Визуализировать корреляции и кластеры
- Сравнивать
scatter()иplot()





