Точечные диаграммы Matplotlib в Python — полное руководство
Создание и настройка точечных диаграмм в Python с Matplotlib: цвет, размер, прозрачность, цветовая шкала, несколько групп и аннотации.
Функция scatter() в Matplotlib позволяет визуализировать зависимость между двумя числовыми переменными, размещая маркер в каждой точке (x, y). В отличие от линейного графика, точечные диаграммы не предполагают ни порядка, ни непрерывности — каждая точка самостоятельна. Это делает их основным инструментом для изучения корреляций, поиска кластеров и обнаружения выбросов.
В этой главе рассматривается всё — от первой точечной диаграммы до профессиональных техник: кодирование цвета и размера каждой точки, прозрачность, цветовые шкалы, многогрупповые графики, аннотации точек и сохранение файлов, готовых к публикации.
Перед началом убедитесь, что Matplotlib установлен:
pip install matplotlibЕсли вы только знакомитесь с Matplotlib, сначала прочитайте главы Введение в Matplotlib и Начало работы.
Когда использовать точечную диаграмму
Используйте точечную диаграмму, когда:
- Вы хотите изучить корреляцию между двумя числовыми переменными (рост и вес, часы учёбы и оценка на экзамене).
- Вам нужно обнаружить кластеры — группы точек, которые естественно сближаются.
- Вы хотите выявить выбросы — точки, далеко отстоящие от основного распределения.
- Вы кодируете третью переменную через размер или цвет маркера («пузырьковая диаграмма» — это точечная диаграмма, где размер = третья переменная).
Избегайте точечных диаграмм, когда одна ось представляет неупорядоченные категории — там нагляднее столбчатая диаграмма. Для отображения трендов по непрерывной упорядоченной переменной лучше подходит линейный график.
Создание базовой точечной диаграммы
Передайте в plt.scatter() две последовательности одинаковой длины — значения x и значения y:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [2, 4, 5, 4, 7, 8, 6, 9, 10, 12]
plt.scatter(x, y)
plt.title('Basic Scatter Plot')
plt.xlabel('X Values')
plt.ylabel('Y Values')
plt.tight_layout()
plt.show()plt.tight_layout() предотвращает обрезку подписей — сделайте это привычкой перед каждым вызовом show() или savefig().
Настройка размера маркеров
Параметр s управляет размером маркера в квадратных пунктах (по умолчанию 20). Увеличьте его, чтобы точки были лучше видны, особенно в презентациях:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [3, 1, 4, 1, 5, 9, 2, 6]
plt.scatter(x, y, s=120)
plt.title('Larger Markers')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()В s можно передать список или array, чтобы каждая точка имела собственный размер — именно так кодируется третья числовая переменная в виде площади пузырька:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [5, 3, 6, 2, 7]
sizes = [100, 300, 50, 400, 200] # third variable encoded as bubble area
plt.scatter(x, y, s=sizes)
plt.title('Bubble Chart — size encodes a third variable')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()Настройка цвета маркеров
Один цвет для всех точек
Передайте имя цвета, hex-строку или RGB-кортеж в c (или color):
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 5, 3]
plt.scatter(x, y, s=100, c='steelblue')
plt.title('Single Color')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()Цвет каждой точки из числовой переменной
Передача array в c отображает каждое значение на цвет через цветовую карту, указанную в cmap. Добавьте plt.colorbar(), чтобы показать, что означают цвета:
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=42)
x = rng.random(50)
y = rng.random(50)
values = rng.random(50) # third variable, e.g. intensity or temperature
scatter = plt.scatter(x, y, s=80, c=values, cmap='viridis')
plt.colorbar(scatter, label='Intensity')
plt.title('Color-Mapped Scatter Plot')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()'viridis' — перцептивно равномерная цветовая карта, читаемая в оттенках серого и доступная для людей с нарушением цветового восприятия. Другие хорошие варианты: 'plasma', 'cividis' и 'coolwarm'.
Управление прозрачностью с помощью alpha
Когда много точек перекрываются, они образуют непрозрачное пятно, скрывающее реальную плотность. Задайте alpha (0 = полностью прозрачный, 1 = полностью непрозрачный), чтобы обнажить структуру перекрытий:
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=0)
x = rng.normal(loc=0, scale=1, size=300)
y = rng.normal(loc=0, scale=1, size=300)
plt.scatter(x, y, s=40, alpha=0.4)
plt.title('Transparent Markers Reveal Density (alpha=0.4)')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()Хорошей отправной точкой является alpha=0.4 до 0.6. Подбирайте значение в зависимости от количества точек.
Стилизация границ маркеров
Используйте edgecolors, чтобы добавить рамку вокруг каждого маркера, и linewidths, чтобы управлять её толщиной. Это помогает точкам выделяться на цветном фоне:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5, 6]
y = [3, 1, 4, 1, 5, 9]
plt.scatter(x, y, s=150, c='gold', edgecolors='black', linewidths=1.5)
plt.title('Markers with Edges')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()Передайте edgecolors='none', чтобы полностью убрать рамки (это значение по умолчанию для большинства цветовых карт).
Отображение нескольких групп
Для сравнения групп вызывайте plt.scatter() по одному разу для каждой группы и задавайте метку. Matplotlib автоматически присваивает разный цвет каждому вызову:
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=7)
# Group A — centered around (2, 3)
ax_x = rng.normal(loc=2, scale=0.5, size=30)
ax_y = rng.normal(loc=3, scale=0.5, size=30)
# Group B — centered around (5, 6)
bx_x = rng.normal(loc=5, scale=0.5, size=30)
bx_y = rng.normal(loc=6, scale=0.5, size=30)
# Group C — centered around (8, 2)
cx_x = rng.normal(loc=8, scale=0.5, size=30)
cx_y = rng.normal(loc=2, scale=0.5, size=30)
plt.scatter(ax_x, ax_y, s=60, label='Group A')
plt.scatter(bx_x, bx_y, s=60, label='Group B')
plt.scatter(cx_x, cx_y, s=60, label='Group C')
plt.legend()
plt.title('Multi-Group Scatter Plot')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()Каждый вызов scatter() автоматически берёт следующий цвет из стандартного цикла. Передайте c='red' (или любой цвет), чтобы переопределить его.
Аннотирование отдельных точек
Используйте plt.annotate() для подписи конкретных точек — это удобно для выделения выбросов или ключевых наблюдений:
import matplotlib.pyplot as plt
cities = ['London', 'Berlin', 'Madrid', 'Rome', 'Paris']
population = [9.0, 3.7, 3.3, 2.8, 2.1] # millions
area = [1572, 892, 604, 1285, 105] # km²
plt.scatter(area, population, s=100, c='steelblue', edgecolors='black', linewidths=0.8)
for i, city in enumerate(cities):
plt.annotate(
city,
xy=(area[i], population[i]),
xytext=(8, 4), # offset in points
textcoords='offset points',
fontsize=9,
)
plt.title('European City Population vs. Area')
plt.xlabel('Area (km²)')
plt.ylabel('Population (millions)')
plt.tight_layout()
plt.show()Паттерн xytext + textcoords='offset points' немного смещает подпись, чтобы она не накладывалась непосредственно на маркер.
Использование логарифмических осей
Когда данные охватывают несколько порядков величины, линейные оси сжимают большинство точек в один угол. Переключитесь на логарифмический масштаб с помощью plt.xscale('log') или plt.yscale('log'):
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=1)
x = np.logspace(1, 5, 60) # 10¹ to 10⁵
y = x * rng.uniform(0.5, 2.0, 60) # roughly proportional, with noise
plt.scatter(x, y, s=40, alpha=0.7)
plt.xscale('log')
plt.yscale('log')
plt.title('Log-Scale Scatter Plot')
plt.xlabel('X (log scale)')
plt.ylabel('Y (log scale)')
plt.tight_layout()
plt.show()Обе оси теперь охватывают равные интервалы степеней десяти, равномерно распределяя данные по области графика.
Добавление линии регрессии
Точечная диаграмма показывает отдельные точки; добавление линии наилучшего соответствия демонстрирует общий тренд. Вычислите наклон и сдвиг с помощью np.polyfit():
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=3)
x = np.linspace(0, 10, 40)
y = 2.5 * x + rng.normal(scale=3, size=40) # linear trend + noise
# Fit a degree-1 polynomial (straight line)
slope, intercept = np.polyfit(x, y, 1)
trend_line = slope * x + intercept
plt.scatter(x, y, s=50, label='Data points', alpha=0.7)
plt.plot(x, trend_line, color='red', linewidth=2, label=f'Trend (slope={slope:.2f})')
plt.legend()
plt.title('Scatter Plot with Regression Line')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()np.polyfit(x, y, 1) возвращает [slope, intercept] для линии наилучшего соответствия, проходящей через точки.
Сохранение точечной диаграммы в файл
Используйте plt.savefig() вместо plt.show(), чтобы записать диаграмму на диск. Вызывайте его до plt.show() — после show() фигура очищается:
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=9)
x = rng.random(60)
y = rng.random(60)
plt.scatter(x, y, s=60, alpha=0.6, c='teal', edgecolors='white', linewidths=0.5)
plt.title('Saved Scatter Plot')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.savefig('scatter.png', dpi=150) # PNG at 150 DPI
plt.savefig('scatter.pdf') # vector PDF — best for publication
plt.show()Распространённые форматы: 'png' (растр, веб), 'pdf' (вектор, публикация), 'svg' (вектор, веб). Увеличьте dpi до 300 для растров печатного качества.
scatter() vs plot() — что выбрать?
Обе функции могут строить графики только из маркеров, но служат разным целям:
| Возможность | plt.scatter() | plt.plot() |
|---|---|---|
Размер каждой точки (s) | Да — передайте array | Нет |
Цвет каждой точки (c) | Да — передайте array | Нет (один цвет на вызов) |
| Поддержка цветовой карты | Да (cmap) | Ограниченная |
| Производительность на больших наборах данных | Медленнее | Быстрее |
| Соединяющая линия | Нет | Да |
Используйте scatter(), когда нужна индивидуальная стилизация точек (цвет или размер зависят от данных). Используйте plot(marker='o', linestyle='None') для простых графиков на больших наборах данных, где важна скорость. Подробнее о стилях маркеров — в главе Маркеры Matplotlib.
Полный пример
Следующий самодостаточный скрипт объединяет наиболее полезные техники — отображение цвета, кодирование размера, прозрачность, цветовую шкалу и легенду:
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=42)
n = 80
x = rng.standard_normal(n)
y = 0.8 * x + rng.standard_normal(n) * 0.6 # correlated
sizes = rng.uniform(30, 200, n) # bubble area
values = rng.random(n) # third variable for color
fig, ax = plt.subplots(figsize=(8, 5))
sc = ax.scatter(
x, y,
s=sizes,
c=values,
cmap='plasma',
alpha=0.75,
edgecolors='white',
linewidths=0.5,
)
plt.colorbar(sc, ax=ax, label='Intensity')
ax.set_title('Comprehensive Scatter Plot Example', fontsize=13)
ax.set_xlabel('X Variable')
ax.set_ylabel('Y Variable (correlated)')
fig.tight_layout()
plt.savefig('scatter_complete.png', dpi=150)
plt.show()Ключевые моменты:
fig, ax = plt.subplots()даёт вам явные объекты фигуры и осей — рекомендуемый подход для всего, что выходит за рамки быстрого прототипа.ax.scatter()для объектаAxesведёт себя идентичноplt.scatter().plt.colorbar(sc, ax=ax, label='...')прикрепляет цветовую шкалу к конкретным осям.
Лучшие практики
- Показывайте шкалу. Если используете
cс цветовой картой, всегда добавляйте цветовую шкалу, чтобы читатели понимали, что означают цвета. - Избегайте наложения точек. При более чем ~500 точках задайте
alpha < 1или перейдите к 2D-гистограмме (plt.hist2d()) или шестиугольной диаграмме (plt.hexbin()). - Выбирайте доступные цветовые карты.
'viridis','plasma'и'cividis'— перцептивно равномерные и дружественные к людям с нарушением цветового восприятия. Избегайте'jet'и'rainbow'. - Подписывайте оси с единицами.
plt.xlabel('Height (cm)')информативнее, чемplt.xlabel('Height'). - Добавляйте заголовок, отражающий вывод. «Рост vs. Вес — положительная корреляция» полезнее, чем «Точечная диаграмма».
Связанные главы
- Введение в Matplotlib — обзор библиотеки и установка
- Начало работы с Matplotlib — первые графики
- Линейные графики Matplotlib — тренды по непрерывным переменным
- Столбчатые диаграммы Matplotlib — сравнение дискретных категорий
- Гистограммы Matplotlib — распределение одной переменной
- Маркеры Matplotlib — все стили маркеров и параметры настройки
- Подграфики Matplotlib — объединение нескольких диаграмм в одной фигуре