Matplotlib: полное руководство по визуализации данных

Разбираем построение графиков с примерами

Matplotlib: полное руководство по визуализации данных

Тема на сегодня — визуализация данных на Python. 

Универсальных инструментов в ИТ не бывает, поэтому очень важно, чтобы технологию можно было расширить дополнительными возможностями под конкретную задачу. В этом смысле Python — практически идеальный язык программирования. С ним можно делать всё: автоматизировать процессы, писать веб-приложения, создавать игры, визуализировать данные — про последнее и поговорим. А заодно разберём одну из самых популярных библиотек визуализации — Matplotlib.

Что такое Matplotlib и зачем она нужна

Библиотека Matplotlib — набор инструментов визуализации данных на Python.

Python хорошо подходит для аналитики, с ним удобно работать с базами данных и большими датасетами. Но просто смотреть на цифры неудобно: так может быть сложно найти закономерности и вычислить важные показатели.

С Matplotlib Python становится мощным наглядным инструментом анализа. Если задать правильный вопрос и построить несколько графиков, то вполне можно найти ответ и предложить решение. 

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

Что делать с этими данными — будут решать менеджеры и директора. Задача аналитиков и разработчиков в том, чтобы показать информацию так, чтобы она помогла принять решение. 

Matplotlib — это возможность представить данные максимально эффективно. Мы для примера взяли простой график, но в библиотеке можно работать с визуализациями разной сложности, в том числе 3D. Например, можно сделать такую трёхмерную картинку и говорить всем, что ты теперь тридэ-девелопер:

Источник: matplotlib.org

Как появилась Matplotlib и что работает под капотом

При работе с Matplotlib часто можно встретить три названия:

  • MATLAB,
  • Pylab,
  • Pyplot.

Разберём всё по очереди.

MATLAB — инструмент для визуализации данных, как и Matplotlib. Используется учёными, инженерами и аналитиками для работы с матрицами, построения графиков, аналитики, машинного обучения и других задач. MATLAB прост в использовании, потому что позволяет выполнять сложные математические операции с помощью коротких команд.

Но у MATLAB есть один недостаток — он платный. Python тоже простой и удобный для работы с данными, к тому же бесплатный. Но сам по себе Python не умеет строить графики. Когда разработчики решили добавить такую возможность, они взяли за ориентир принципы MATLAB.

Pyplot — это пакет, который упрощает создание графиков. Он делает процесс похожим на то, как это делается в MATLAB.

Pylab — ещё один модуль, который облегчал переход с MATLAB на Matplotlib. Он устанавливался вместе с библиотекой и автоматически импортировал два необходимых для работы модуля: matplotlib.pyplot и библиотеку для более быстрой и удобной работы numpy. При работе с MATLAB ничего импортировать не нужно, поэтому сначала с Matplotlib тоже работали без явного импорта. 

Но позже от такого отказались по двум причинам:

  • Вызывать библиотеки неявно — плохо. Можно запутаться в коде и получить конфликты в программе.
  • Программисты на Python привыкли импортировать все модули вручную.

Сейчас принято чётко обозначать модули, с которыми мы работаем. Поэтому код для работы с Matplotlib почти всегда начинается с двух строк (тут сразу ещё подключаем NumPy, чтобы проще было обрабатывать числа перед визуализацией):

import matplotlib.pyplot as plt 
import numpy as np

Основные концепции и терминология

В Python Matplotlib использует объектно-ориентированную модель для построения изображения. График состоит из двух основных объектов:

  • Figure (Фигура) — основное полотно-контейнер, на котором размещаются графики.
  • Axes (Оси) — область внутри фигуры, где рисуется конкретный график. Отдельные координатные оси X или Y внутри Axes будут называться Axis. У одной Figure может быть несколько Axes.

Чтобы строить графики, есть два способа:

  • Упрощённый и более быстрый — используя Pyplot. Этот вариант удобен для быстрых построений, но скрывает тонкие настройки Matplotlib.
  • Точно настраиваемый — через Axes. Это позволяет гибко управлять графиком, когда необходимы сложные визуализации.

Установка и начало работы с Matplotlib

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

Если код вы пишете в текстовом редакторе, например Sublime, команду нужно выполнить в терминале командной строки, предварительно зайдя в корневую папку проекта:

При работе в среде разработки IDE команду нужно запустить на вкладке терминала:

Первыми двумя строками кода импортируем модуль Pyplot и библиотеку NumPy:

import matplotlib.pyplot as plt 
import numpy as np

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

Типы графиков и диаграмм в Matplotlib

Есть несколько основных типов визуализаций, с которыми работают в Matplotlib. Как правило, код для них объединяет несколько одинаковых настроек:

  • импорт Pyplot и NumPy командами import matplotlib.pyplot as plt и import numpy as np;
  • подписи осей командами plt.xlabel() и plt.ylabel();
  • установка заголовка графика командой plt.title();
  • отрисовка графика — plt.show().

Линейные графики

Используются для отображения зависимости одной переменной от другой. Они хорошо подходят для временных рядов и трендов: анализа цен на акции, графиков температур, зависимостей продаж от времени, математических функций.

Для примера построим график зависимости функции синуса от значения переменной x. Всё как в школе, только не на доске, а на компьютере, но тоже вручную:

# импортируем библиотеку NumPy
import numpy as np
# импортируем из matplotlib pyplot
import matplotlib.pyplot as plt

# создаём массив из 100 точек от 0 до 10
x = np.linspace(0, 10, 100)
# вычисляем синус от каждого значения X
y = np.sin(x)

# строим график синуса с меткой и цветом
plt.plot(x, y, label="sin(x)", color="blue") 
# подписываем ось X
plt.xlabel("Время")
# подписываем ось Y
plt.ylabel("Значение")
# задаём заголовок графика
plt.title("Линейный график") 
# отображаем легенду (метку "sin(x)")
plt.legend()
# показываем график
plt.show()

Запускаем код, получаем график:

Диаграммы рассеяния (Scatter Plot) 

Показывают корреляцию, связь между данными. Такие графики будут полезны для анализа роста людей в зависимости от веса или распределения цен квартир по районам.

Пример: мы получаем 100 точек со случайными координатами по двум осям и выводим их на экран. Для этого используем генератор случайных чисел из библиотеки NumPy — np.random.rand:

# импортируем библиотеку NumPy
import numpy as np
# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# генерируем 100 случайных значений от 0 до 10 (ось X)
x = np.random.rand(100) * 10
# генерируем 100 случайных значений от 0 до 10 (ось Y)
y = np.random.rand(100) * 10

# строим точки красного цвета, alpha — прозрачность
plt.scatter(x, y, color="red", alpha=0.5)
# подписываем ось X
plt.xlabel("Переменная X")
# подписываем ось Y
plt.ylabel("Переменная Y")
# задаём заголовок графика
plt.title("Диаграмма рассеяния")
# показываем график
plt.show()

Отрисовываем график:

В примере мы использовали случайные значения, поэтому график тоже получился хаотичным (и в этом виде практического смысла в нём никакого). Но если бы на осях расположились реальные показатели, визуализация могла бы дать какой-то ответ, например что самые дешёвые квартиры находятся в двух районах города из 10.

Гистограммы

Они демонстрируют распределение данных и показывают, сколько значений попадает в определённые интервалы. Предметами анализа могут быть оценки студентов, распределения доходов, частота слов в тексте — что угодно, где есть какие-то диапазоны. Один интервал может обозначать класс в школе, возраст сотрудников в компании, автора книг или статей. 

Для примера попросим Matplotlib заполнить 30 абстрактных интервалов случайными значениями. После визуализации увидим, сколько значений попало в каждый интервал:

# импортируем библиотеку NumPy
import numpy as np
# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# генерируем 1 000 случайных значений с нормальным распределением
data = np.random.randn(1000)

# создаём гистограмму с 30 интервалами (бинами)
plt.hist(data, bins=30, color="green", alpha=0.7)
# подписываем ось X
plt.xlabel("Значения")
# подписываем ось Y
plt.ylabel("Частота")
# задаём заголовок графика
plt.title("Гистограмма распределения")
# показываем график
plt.show()

Запускаем визуализацию. Чем выше зелёный столбец — тем сильнее он заполнен. Если что — перед нами классическое распределение по Гауссу, которое встречается почти везде, где есть числа и их распределение.

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

С их помощью сравнивают разные категории по числовому значению. Это хороший способ отображения сравнения продаж по месяцам или популярности языков программирования. Здесь для каждой категории нужно задать значения и потом передать их в команду построения графика.

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

# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# категории
using = ["Python", "Java", "C++", "JavaScript"]
# значения для каждой категории
visualization = [24, 11, 12, 4]

# строим столбчатую диаграмму
plt.bar(using, visualization, color="purple")
# подписываем ось X
plt.xlabel("Языки программирования")
# подписываем ось Y
plt.ylabel("Популярность")
# задаём заголовок графика
plt.title("Столбчатая диаграмма")
# показываем график
plt.show()

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

Показывают отображение каждого сектора в общем объёме: доли на рынке, категории расходов, составление бюджета. Для визуализации долей им нужно дать названия, задать значения и цвет отображения.

Допустим, мы хотим наглядно показать своей второй половинке, на что уходит семейный бюджет. Можно попробовать объяснить на словах, а можно построить график, чтобы добавить +100 к весомости аргументов:

# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# подписи для секторов
labels = ["Еда", "Транспорт", "Жильё", "Развлечения"]
# процентное соотношение секторов
sizes = [30, 20, 40, 10]

# передаём размеры секторов, их названия и цвета, autopct="%1.1f%%" отображает процент внутри каждого сектора
plt.pie(sizes, labels=labels, autopct="%1.1f%%", colors=["blue", "red", "green", "yellow"])
# задаём заголовок графика
plt.title("Круговая диаграмма")
# показываем график
plt.show()

Смотрим, что получается:

Boxplot

Диаграмма, визуально похожая на популярный график для анализа ценных бумаг «японские свечи». Boxplot используется для изучения разброса данных и выявления выбросов. Это может быть анализ зарплат в компании, сравнение результатов тестов, изучение разброса цен.

Для примера построим 4 группы данных, каждую с разным разбросом значений от 1 до 100. Получится список data из 4 элементов:

# импортируем библиотеку NumPy
import numpy as np
# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# cоздаём 4 группы данных, каждая с разным разбросом
data = [np.random.randn(100) * i for i in range(1, 5)]

# cтроим диаграмму размаха
plt.boxplot(data)
# подписываем ось X
plt.xlabel("Группы данных")
# подписываем ось Y
plt.ylabel("Значения")
# задаём заголовок графика
plt.title("Boxplot")
# показываем график
plt.show()

Из каких элементов состоит визуализация каждой группы:

  • Прямоугольник показывает основной разброс данных между 25% и 75%.
  • Вертикальные линии показывают диапазон данных, исключая выбросы.
  • Точки за пределами линий показывают выбросы, очень маленькие или большие значения.
  • Оранжевая горизонтальная линия в коробке показывает медианное значение.

3D-графики

Позволяют визуализировать данные в трёхмерном пространстве. Применяются для анализа поверхностей, демонстрации географических данных и моделирования физических процессов.

Для примера мы создадим волнообразную поверхность. Чтобы Matplotlib понял, что мы хотим нарисовать 3D-график, добавим в окно объекта Figure 3D-ось командой: 

ax = fig.add_subplot(111, projection="3d")

В начале мы говорили, что фигура — это главное окно визуализации, и она может содержать в себе несколько графиков. Метод fig.add_subplot() добавляет подграфик на фигуру. Иногда подграфики создаются автоматически, как в предыдущих примерах, но иногда их надо создать явно, добавив такую команду в код.

Нам нужно добавить подграфик явно, потому что мы хотим сделать 3D-визуализацию. Без нашей команды Matplotlib всё равно добавит подграфик, но сделает это неявно и без добавления 3D-оси.

# импортируем библиотеку NumPy
import numpy as np
# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# создаём массив значений от −5 до 5 (ось X)
x = np.linspace(-5, 5, 30)
# создаём массив значений от −5 до 5 (ось Y)
y = np.linspace(-5, 5, 30)
# cоздаём сетку координат
X, Y = np.meshgrid(x, y)
# вычисляем Z-координаты (волнообразная поверхность)
Z = np.sin(np.sqrt(X**2 + Y**2))

# создаём фигуру для графика
fig = plt.figure()
# добавляем 3D-ось
ax = fig.add_subplot(111, projection="3d")
# строим 3D-поверхность с цветовой схемой
ax.plot_surface(X, Y, Z, cmap="viridis")
# задаём заголовок графика
plt.title("3D-график")
# показываем график
plt.show()

Тепловые карты

Такие карты используются для отображения интенсивности значений. Они удобны в анализе различных зон в городах, картах активности пользователей или других анализах, где можно показать разный уровень активности. Помните наш проект с анализом твитов Трампа и Байдена? Это как раз оно.

Для примера создадим матрицу случайных значений размером 10 × 10 клеток. Каждой клетке будет соответствовать значение от 1 до 10. Чем ближе значение к верхнему, тем более красным оно будет, чем ниже — более синим:

# импортируем библиотеку NumPy
import numpy as np
# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# создаём случайную матрицу 10 × 10 значений
data = np.random.rand(10, 10)

# используем для графика созданную матрицу, imshow отображает
# матрицу как изображение, cmap — цветовая схема, interpolation="nearest"
# означает, что мы отображаем пиксели без сглаживания
plt.imshow(data, cmap="coolwarm", interpolation="nearest")
# добавляем шкалу значений
# задаём заголовок графика
plt.colorbar()
# задаём заголовок графика
plt.title("Тепловая карта")
# показываем график
plt.show()

Сложные визуализации

Matplotlib позволяет комбинировать несколько графиков и использовать продвинутые библиотеки, например Seaborn или Plotly. Это полезно для анализа сложных данных, для некоторых отчётов или визуализации нейросетей.

Мы сделаем визуализацию с библиотекой seaborn. Это будет продвинутая тепловая карта, где внутри ячеек будут располагаться числа:

# импортируем библиотеку Seaborn
import seaborn as sns
# импортируем библиотеку NumPy
import numpy as np
# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# генерируем случайную матрицу 10 × 12
use = np.random.rand(10, 12)

# создаём тепловую карту с числами внутри ячеек
sns.heatmap(use, annot=True, cmap="YlGnBu")
# задаём заголовок графика
plt.title("Тепловая карта с Seaborn")
# показываем график
plt.show()

Настройка графиков

Изменение стилей и цветов

Matplotlib позволяет изменять внешний вид графиков, чтобы они соответствовали разным требованиям. Что можно менять и какие параметры за это отвечают:

  • color меняет цвет линии или маркера.
  • linestyle задаёт стиль линии — прерывистый, пунктирный, точечный.
  • marker настраивает стили маркеров. Это символы, которые отмечают точки на графике.
  • linewidth задаёт толщину линии.
  • alpha — параметр прозрачности линии или маркера. Значение можно устанавливать от 0 до 1.

Добавление подписей и аннотаций

Подписи делают график более информативным. Что можно добавить:

  • plt.title() устанавливает заголовок графика.
  • plt.xlabel() и plt.ylabel() задают подписи осей по X и Y.
  • plt.legend() добавляет легенду. Это пояснения, что обозначают разные линии или маркеры на графике.
  • plt.annotate() наносят на график аннотации — текстовые пояснения, которые можно добавить в любую точку.

Работа с осями

Настройка осей — это про то, как данные отображаются на графике:

  • plt.xlim() и plt.ylim() устанавливают пределы для осей X и Y.
  • plt.grid() добавляет сетку, которая помогает легче читать график.
  • plt.xticks() и plt.yticks() наносят деления на оси.
  • Можно создавать двойные оси для второго набора данных. Например, вторая ось Y создаётся командой ax2 = ax1.twinx().

Комбинирование различных графиков

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

Для примера совместим линейный график, точечный график и гистограмму (допустим, нам так нужно). На нашей визуализации будут такие данные:

  • Линейный график для общего тренда продаж.
  • Точечный график для выделения пиковых месяцев.
  • Гистограмму для распределения продаж по месяцам.

Данные создадим через модуль random из библиотеки NumPy. В качестве шкалы возьмём 12 месяцев:

# импортируем библиотеку NumPy
import numpy as np
# импортируем из Matplotlib Pyplot
import matplotlib.pyplot as plt

# данные:
# месяцы (1–12)
x = np.arange(1, 13)
# продажи
y1 = np.random.randint(50, 200, size=12)
# пиковые продажи
y2 = np.random.randint(50, 200, size=12)

# создаём фигуру и оси
fig, ax = plt.subplots()

# создаём линейный график
ax.plot(x, y1, label="Общие продажи", color="blue")
# создаём точечный график
ax.scatter(x, y2, label="Пиковые продажи", color="red")
# создаём гистограмму
ax.bar(x, y1, alpha=0.3, label="Распределение продаж", color="green")

# добавляем легенду
ax.legend()
# показываем график
plt.show()

Примеры использования Matplotlib

На самом деле у Matplotlib нет какой-то области, где эту библиотеку используют чаще всего. Графики нужны всем, поэтому знание этого инструмента может помочь в разных ситуациях. Если выделить что-то основное, где Matplotlib пригождается постоянно, то вот:

  • Анализ данных — для визуализации показателей и поиска закономерностей.
  • Научные исследования — для работы с экспериментальными данными, графиками функций, 3D-моделями, тепловыми картами.
  • Машинное обучение — для наглядной демонстрации результатов обучения моделей.
  • Финансы — для построения графиков цен на акции, индикаторов и прогнозов.
  • Инженерия — для моделирования систем, анализа данных с датчиков.
  • Образование — используется в учебных материалах для наглядных объяснений.

Часто задаваемые вопросы о Matplotlib

В чём ключевые отличия Matplotlib от более современных библиотек, например Plotly или Seaborn?

Библиотека Matplotlib — мощный инструмент визуализации. Она даёт много возможностей и полный контроль над каждым пикселем графика, но за это приходится писать больше кода. Если нужно построить простую диаграмму, лучше выбрать другую библиотеку, потому что с Matplotlib придётся вносить много деталей вручную. Зато если нужна сложная настройка или визуализация с точными параметрами для научной публикации, Matplotlib — идеальный помощник.

Seaborn построена прямо на Matplotlib и упрощает работу над статичными графиками. Если вы хотите сделать регрессионный анализ или тепловую карту с помощью одной строки кода — Seaborn выручит. Но сложную визуализацию лучше доверить Matplotlib.

Plotly — про интерактивность и веб. Графики, которые сделаны с её помощью, можно масштабировать, и по ним можно перемещаться. Идеально для веб-приложений и дашбордов, но при отображении очень больших наборов данных в браузере интерактивность может снижать производительность.

Можно ли создавать интерактивные графики и дашборды на Matplotlib?

Технически можно, но она для этого не предназначена. Matplotlib создана для статичных графиков. Интерактивность в ней работает, но с оговорками. Так, в Jupyter Notebook можно использовать интерактивный backend, который включает масштабирование и перемещение. Например, %matplotlib widget

Если нужно что-то серьёзнее — например, дашборд, где при клике на график обновляются другие графики, или фильтр, который показывает разные данные, — Matplotlib не подойдёт. Для этого есть другие инструменты.

Plotly + Dash — это королевский набор для дашбордов. Dash построена на Plotly и позволяет создавать интерактивные веб-приложения исключительно на Python, без HTML и JavaScript. Вот простой пример:

import dash
import plotly.express as px
import pandas as pd

app = dash.Dash(__name__)

# Создаём интерактивный график
df = px.data.gapminder()
fig = px.scatter(df, x="gdpPercap", y="lifeExp", 
                 animation_frame="year", size="pop",
                 color="continent")

app.layout = dash.html.Div([
    dash.dcc.Graph(figure=fig)
])

if __name__ == '__main__':
    app.run_server(debug=True)

Matplotlib + виджеты — если очень хочется использовать Matplotlib в интерактивном режиме в Jupyter, можно подключить виджеты ipywidgets. Но это больше для прототипов, а не для боевых дашбордов.

Как сохранить построенный график в файл (PNG, PDF, SVG) высокого качества для отчёта или презентации?

Matplotlib пишет файлы через метод savefig(). Есть несколько трюков, которые помогут получить качественный результат.

Базовый способ:

import matplotlib.pyplot as plt

plt.plot([1, 2, 3], [1, 4, 9])
plt.savefig('график.png')
plt.show()

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

plt.savefig('график.png', 
     # Высокое разрешение для печати
            dpi=300,  
     # Убирает лишние белые поля            
            bbox_inches='tight', 
     # Белый фон 
            facecolor='white',
     # Без чёрной рамки    
            edgecolor='none')  

Разберём параметры:

dpi (dots per inch) — это разрешение. Для экрана обычно хватает 100–150 dpi, но для печати или презентации берите 300 dpi. Да, файл будет весить больше, но качество сохранится. dpi не влияет на векторные форматы типа pdf и svg.

bbox_inches='tight' — полезный параметр. По умолчанию Matplotlib оставляет белые поля вокруг графика, а этот параметр их убирает.

facecolor и edgecolor — цвет фона и рамки. Обычно нужен белый фон без рамки.

Форматы и когда их использовать:

PNG — универсальный формат. Поддерживает прозрачность, хорошо сжимается. Идеален для веб-приложений и презентаций:

plt.savefig('график.png', dpi=300, transparent=True)

PDF — векторный формат, идеален для печати и научных публикаций. Не теряет качество при увеличении:

plt.savefig('график.pdf', bbox_inches='tight')

SVG — векторный, масштабируемый формат. Удобен, если график потом будут менять или встраивать в веб-приложение:

plt.savefig('график.svg', bbox_inches='tight')

JPG — растровый формат, подойдёт, если нужен маленький размер файла, например для отправки по почте. Главный минус: потеря качества:

plt.savefig('график.jpg', dpi=300, quality=95)

Профессиональный рецепт для отчёта:

# Создание крупного графика с высоким качеством
import matplotlib.pyplot as plt

x = range(10)
y = [i**2 for i in x]

fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, y, linewidth=2)
ax.set_xlabel('X', fontsize=14)
ax.set_ylabel('Y', fontsize=14)
ax.set_title('Заголовок графика', fontsize=16, weight='bold')
ax.grid(True, alpha=0.3)

# Сохраняем для печати
fig.savefig('otchet.pdf',
           dpi=300,
           bbox_inches='tight',
           facecolor='white',
           edgecolor='none',
           pad_inches=0.3)

plt.close(fig)

Для множества графиков в один PDF:

from matplotlib.backends.backend_pdf import PdfPages

pdf = PdfPages('множество_графиков.pdf')

for i in range(3):
    fig, ax = plt.subplots()
    ax.plot(range(10))
    ax.set_title(f'График {i+1}')
    pdf.savefig(fig)
    plt.close()

pdf.close()

Как эффективно визуализировать большие объёмы данных (миллионы точек) в Matplotlib без «подвисания»?

Когда у вас есть миллион точек данных, Matplotlib начинает «виснуть». Обычный scatter() создаёт отдельный графический объект для каждой точки. Это может привести к тому, что на создание графика уйдёт 30 секунд, а масштабирование вообще не будет работать.

Есть несколько способов ускорить процесс.

Способ 1: Используйте plt.plot() вместо plt.scatter() для простых случаев

# Медленно (миллион точек)
plt.scatter(x, y, s=1)

# Быстро (если не нужна индивидуальная настройка размера/цвета)
plt.plot(x, y, 'o', markersize=1)

plot() работает быстрее, потому что не создаёт отдельный объект для каждой точки.

Способ 2: Разделите точки по цветам и рисуйте их отдельно

Если у вас есть разные группы данных и вы хотите их раскрасить в разные цвета, не рисуйте весь миллион точек в одном scatter(). Разделите на группы:

import numpy as np
import matplotlib.pyplot as plt

# Генерируем миллион точек в 5 группах
N = 1_000_000
groups = np.random.randint(0, 5, N)
x = np.random.random(N)
y = np.random.random(N)

# Медленный способ
# plt.scatter(x, y, c=groups)

# Быстрый способ: рисуем каждую группу отдельно
colors = ['red', 'blue', 'green', 'yellow', 'purple']
for group in range(5):
    mask = groups == group
    plt.scatter(x[mask], y[mask], c=colors[group], s=1, alpha=0.5)

plt.show()

Это работает примерно в 5–10 раз быстрее.

Способ 3: Используйте datashader для экстремальных случаев

Если у вас десятки миллионов точек и даже оптимизированный Matplotlib не спасает, заходит datashader. Это специальная библиотека для визуализации больших данных:

import datashader as ds
import pandas as pd
import matplotlib.pyplot as plt

# Создаём DataFrame с 10 миллионами точек
df = pd.DataFrame({
    'x': np.random.random(10_000_000),
    'y': np.random.random(10_000_000)
})

# Datashader растеризует данные в пиксели (вместо рисования каждой точки)
cvs = ds.Canvas(plot_width=500, plot_height=500)
agg = cvs.points(df, 'x', 'y')

# Конвертируем в изображение и показываем через matplotlib
img = ds.tf.shade(agg, how='log').to_pil()
plt.imshow(img)
plt.axis('off')
plt.show()

Datashader работает через растеризацию: вместо того, чтобы рисовать каждую точку отдельно, он считает, сколько точек попадает в каждый пиксель, и закрашивает его соответственно. На 10 миллионов точек график рисуется за секунду.

Способ 4: Уменьшите прозрачность и размер маркера

# Скрываем перекрытие за счёт альфа-канала
plt.scatter(x, y, s=1, alpha=0.1)

Маленькие полупрозрачные точки рисуются быстрее и показывают плотность данных.

Способ 5: Отображайте только подмножество данных

# Если данные отсортированы случайно, берём каждую 100-ю точку
step = 100
plt.scatter(x[::step], y[::step], s=2)

Это самый простой способ, если точность не критична.

Сравнение производительности:

МетодСкоростьИнтерактивностьГибкость
scatter() базовый⭐⭐⭐
plot() с маркерами⭐⭐⭐⭐⭐⭐⭐⭐⭐
Разделение по группам⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
datashader⭐⭐⭐⭐⭐⭐⭐⭐

Для большинства случаев с миллионом точек достаточно комбинации способов 2 и 4: разделить на группы и использовать маленькие полупрозрачные точки. Если даже это не помогает — datashader спасает всегда.

Обложка:

Алексей Сухов

Корректор:

Елена Грицун

Вёрстка:

Кирилл Климентьев

Соцсети:

Юлия Зубарева

Вам может быть интересно
hard
[anycomment]
Exit mobile version