Matplotlib. Урок 4.2. Визуализация данных. Ступенчатый, стековый, точечный график и другие
![]()
В этому уроке рассмотрим на примерах работу со ступенчатым, стековым, stem-графиком и точечным графиком.
- Ступенчатый график
- Стековый график
- Stem-график
- Точечный график
- Статьи с описанием различных вариантов работы с точечными графиками
Ступенчатый график
Рассмотрим еще одни график – ступенчатый. Такой график строится с помощью функции step() , которая принимает следующий набор параметров:
- x: array_like
- набор данных для оси абсцисс
- набор данных для оси ординат
- Задает отображение линии (см. функцию plot() ).
- метки
- Определяет место, где будет установлен шаг.
- ‘pre’ : значение y ставится слева от значения x , т.е. значение y[i] определяется для интервала (x[i-1]; x[i]) .
- ‘post’ : значение y ставится справа от значения x , т.е. значение y[i] определяется для интервала (x[i]; x[i+1]) .
- ‘mid’ : значение y ставится в середине интервала.
x = np.arange(0, 7) y = x where_set = ['pre', 'post', 'mid'] fig, axs = plt.subplots(1, 3, figsize=(15, 4)) for i, ax in enumerate(axs): ax.step(x, y, "g-o", where=where_set[i]) ax.grid()

Стековый график
Для построения стекового графика используется функция stackplot() . Суть его в том, что графики отображаются друг над другом, и каждый следующий является суммой предыдущего и заданного набора данных:
x = np.arange(0, 11, 1) y1 = np.array([(-0.2)*i**2+2*i for i in x]) y2 = np.array([(-0.4)*i**2+4*i for i in x]) y3 = np.array([2*i for i in x]) labels = ["y1", "y2", "y3"] fig, ax = plt.subplots() ax.stackplot(x, y1, y2, y3, labels=labels) ax.legend(loc='upper left')

Верхний край области y2 определяется как сумма значений из наборов y1 и y2 , y3 – соответственно сумма y1 , y2 и y3 .
Stem-график
Визуально этот график выглядит как набор линий от точки с координатами ( x , y ) до базовой линии, в верхней точке ставится маркер:
x = np.arange(0, 10.5, 0.5) y = np.array([(-0.2)*i**2+2*i for i in x]) plt.stem(x, y)

Дополнительные параметры функции stem() :
Реализуем пример, демонстрирующий работу с дополнительными параметрами:
plt.stem(x, y, linefmt="r--", markerfmt="^", bottom=1)

Точечный график
Для отображения точечного графика предназначена функция scatter() . В простейшем виде точечный график можно получить передав функции scatter() наборы точек для x , y координат:
x = np.arange(0, 10.5, 0.5) y = np.cos(x) plt.scatter(x, y)

Для более детальной настройки отображения необходимо воспользоваться дополнительными параметрами функции scatter() , сигнатура ее вызова имеет следующий вид:
scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, *, plotnonfinite=False, data=None, **kwargs)
Рассмотрим некоторые из параметров:
Параметр Тип Описание x array_like, shape (n, ) Набор данных для оси абсцисс y array_like, shape (n, ) Набор данных для оси ординат s scalar или array_like, shape (n, ), optional Масштаб точек c color, sequence, или sequence of color, optional Цвет marker MarkerStyle , optional Стиль точки объекта cmap Colormap , optional, default: None Цветовая схема norm Normalize , optional, default: None Нормализация данных alpha scalar, optional, default: None Прозрачность linewidths scalar или array_like, optional, default: None Ширина границы маркера edgecolors или color или sequence of color, optional. Цвет границы Создадим решение, использующее расширенные параметры для настройки отображения графика:
x = np.arange(0, 10.5, 0.5) y = np.cos(x) plt.scatter(x, y, s=80, c="r", marker="D", linewidths=2, edgecolors="g")

Пример, демонстрирующий работу с цветом и размером:
import matplotlib.colors as mcolors bc = mcolors.BASE_COLORS x = np.arange(0, 10.5, 0.25) y = np.cos(x) num_set = np.random.randint(1, len(mcolors.BASE_COLORS), len(x)) sizes = num_set * 35 colors = [list(bc.keys())[i] for i in num_set] plt.scatter(x, y, s=sizes, alpha=0.4, c=colors, linewidths=2, edgecolors="face") plt.plot(x, y, "g--", alpha=0.4)

Статьи с описанием различных вариантов работы с точечными графиками
P.S.
Вводные уроки по “Линейной алгебре на Python” вы можете найти соответствующей странице нашего сайта . Все уроки по этой теме собраны в книге “Линейная алгебра на Python”.
Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. Для начала вы можете познакомиться с вводными уроками. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.
Matplotlib. Урок 4.2. Визуализация данных. Ступенчатый, стековый, точечный график и другие : 1 комментарий
- Узбек 18.09.2020 Ссайт реально хороший.Ребята все чётко объяснили.Вопросов нет
Matplotlib: как раскрасить диаграмму рассеяния по значению

Часто вы можете захотеть затенить цвет точек на диаграмме рассеяния matplotlib на основе какой-то третьей переменной. К счастью, это легко сделать с помощью функции matplotlib.pyplot.scatter() , которая имеет следующий синтаксис:
matplotlib.pyplot.scatter (x, y, s = нет, c = нет, cmap = нет)
- x: Массив значений, используемых для координат оси X на графике.
- y: Массив значений, используемых для координат оси Y на графике.
- s: Размер маркера.
- c: Массив значений для цветов маркеров.
- cmap: карта цветов для использования в графике.
Вы можете использовать c , чтобы указать переменную, которая будет использоваться для значений цвета, и вы можете использовать cmap , чтобы указать фактические цвета, которые будут использоваться для маркеров на диаграмме рассеивания.
В этом руководстве объясняется несколько примеров использования этой функции на практике.
Пример 1: цвет точек диаграммы рассеяния по значению
Предположим, у нас есть следующие Pandas DataFrame:
import pandas as pd #create DataFrame df = pd.DataFrame() #view DataFrame df x y z 0 25 5 3 1 12 7 4 2 15 7 4 3 14 9 5 4 19 12 7 5 23 9 8 6 25 9 8 7 29 4 9В следующем коде показано, как создать диаграмму рассеивания с использованием карты оттенков серого и значений переменной z в качестве оттенка для карты цветов:
import matplotlib.pyplot as plt #create scatterplot plt.scatter (df.x, df.y, s=200, c=df.z, cmap='gray')
Для этого конкретного примера мы выбрали цветовую карту «серый», но вы можете найти полный список цветовых карт, доступных для использования, в документации по цветовой карте matplotlib .
Например, вместо этого мы могли бы указать «Зеленые» в качестве цветовой карты:
plt.scatter (df.x, df.y, s=200, c=df.z, cmap='Greens')
По умолчанию маркеры с большими значениями аргумента c затемняются темнее, но вы можете изменить это, просто добавив _r к имени cmap:
plt.scatter (df.x, df.y, s=200, c=df.z, cmap='Greens_r')
Пример 2. Цвет точек на диаграмме рассеяния по категориям
Предположим, у нас есть следующие Pandas DataFrame:
import pandas as pd #create DataFrame df = pd.DataFrame() #view DataFrame df x y z 0 25 5 A 1 12 7 A 2 15 7 B 3 14 9 B 4 19 12 B 5 23 9 C 6 25 9 C 7 29 4 CВ следующем коде показано, как создать диаграмму рассеяния, используя переменную z для окрашивания маркеров в зависимости от категории:
import matplotlib.pyplot as plt groups = df.groupby('z') for name, group in groups: plt.plot (group.x, group.y, marker='o', linestyle='', markersize=12, label=name) plt.legend()
Вы можете найти больше руководств по Python здесь .
Язык Python
Библиотека matplotlib содержит большой набор инструментов для двумерной графики. Она проста в использовании и позволяет получать графики высокого качества. В этом разделе мы рассмотрим наиболее распространенные типы диаграмм и различные настройки их отображения.
Модуль matplotlib.pyplot предоставляет процедурный интерфейс к (объектно-ориентированной) библиотеке matplotlib, который во многом копирует инструменты пакета MATLAB. Инструменты модуля pyplot де-факто являются стандартным способом работы с библиотекой matplotlib , поэтому мы органичимся рассмотрением этого пакета.
Двумерные графики
pyplot.plot
Нарисовать графики функций sin и cos с matplotlib.pyplot можно следующим образом:
import numpy as np import matplotlib.pyplot as plt phi = np.linspace(0, 2.*np.pi, 100) plt.plot(phi, np.sin(phi)) plt.plot(phi, np.cos(phi)) plt.show()
В результате получаем

Мы использовали функцию plot, которой передали два параметра — списки значений по горизонтальной и вертикальной осям. При последовательных вызовах функции plot графики строятся в одних осях, при этом происходит автоматическое переключение цвета.
fmt = '[marker][line][color]'
функции plot позволяет задавать тип маркера, тип линии и цвет. Приведем несколько примеров:
x = np.linspace(0, 1, 100) f1 = 0.25 - (x - 0.5)**2 f2 = x**3 plt.plot(x, f1, ':b') # пунктирная синяя линия plt.plot(x, f2, '--r') # штрихованная красная линия plt.plot(x, f1+f2, 'k') # черная непрерывная линия plt.show()

rg = np.random.Generator(np.random.PCG64()) plt.plot(rg.binomial(10, 0.3, 6), 'ob') # синие круги plt.plot(rg.poisson(7, 6), 'vr') # красные треугольники plt.plot(rg.integers(0, 10, 6), 'Dk') # черные ромбы plt.show()

Из последнего примера видно, что если в функцию plot передать только один список y , то он будет использован для значений по вертикальной оси. В качестве значений по горизонтальной оси будет использован range(len(y)) .
Более тонкую настройку параметров можно выполнить, передавая различные именованные аргументы, например:
- marker : str — тип маркера
- markersize : float — размер маркера
- linestyle : str — тип линии
- linewidth : float — толщина линии
- color : str — цвет
Полный список доступных параметров можно найти в документации.
pyplot.errorbar
Результаты измерений в физике чаще всего представлены в виде величин с ошибками. Функция plt.errorbar позволяет отображать такие данные:
rg = np.random.Generator(np.random.PCG64(5)) x = np.arange(6) y = rg.poisson(149, x.size) plt.errorbar(x, y, yerr=np.sqrt(y), marker='o', linestyle='none') plt.show()

Ошибки можно задавать и для значений по горизонтальной оси:
rg = np.random.Generator(np.random.PCG64(5)) N = 6 x = rg.poisson(169, N) y = rg.poisson(149, N) plt.errorbar(x, y, xerr=np.sqrt(x), yerr=np.sqrt(y), marker='o', linestyle='none') plt.show()

Ошибки измерений могут быть асимметричными. Для их отображения в качестве параметра yerr (или xerr ) необходимо передать кортеж из двух списков:
rg = np.random.Generator(np.random.PCG64(11)) N = 6 x = np.arange(N) y = rg.poisson(149, N) yerr = [ 0.7*np.sqrt(y), 1.2*np.sqrt(y) ] plt.errorbar(x, y, yerr=yerr, marker='o', linestyle='none') plt.show()

Функция pyplot.errorbar поддерживает настройку отображения графика с помощью параметра fmt и всех именованных параметров, которые доступны в функции pyplot . Кроме того, здесь появляются параметры для настройки отображения линий ошибок («усов»):
- ecolor : str — цвет линий ошибок
- elinewidth : float — ширина линий ошибок
- capsize : float — длина «колпачков» на концах линий ошибок
- capthick : float — толщина «колпачков» на концах линий ошибок
и некоторые другие. Изменим параметры отрисовки данных из предыдущего примера:
# . plt.errorbar(x, y, yerr=yerr, marker='o', linestyle='none', ecolor='k', elinewidth=0.8, capsize=4, capthick=1) plt.show()

Настройки отображения
Наши графики все еще выглядят довольно наивно. В этой части мы рассмотрим различные настройки, которые позволят достичь качества оформления диаграмм, соответствующего, например, публикациям в рецензируемых журналах.
Диапазон значений осей
Задавать диапазон значений осей в matplotlib можно несколькими способами. Например, так:
pyplot.xlim([0, 200]) # диапазон горизонтальной оси от 0 до 200 pyplot.xlim([0, 1]) # диапазон вертикальной оси от 0 до 1
Размер шрифта
Размер и другие свойства шрифта, который используется в matplotlib по умолчанию, можно изменить с помощью объекта matplotlib.rcParams :
matplotlib.rcParams.update('font.size': 14>)
Объект matplotlib.rcParams хранит множество настроек, изменяя которые, можно управлять поведением по умолчанию. Смотрите подробнее в документации.
Подписи осей
Подписи к осям задаются следующим образом:
plt.xlabel('run number', fontsize=16) plt.ylabel(r'average current ($\mu A$)', fontsize=16)
В подписях к осям (и вообще в любом тексте в matplotlib) можно использовать инструменты текстовой разметки TeX, позволяющие отрисовывать различные математические выражения. TeX-выражения должны быть внутри пары символов $ , кроме того, их следует помещать в r-строки, чтобы избежать неправильной обработки.
Заголовок
Функция pyplot.title задает заголовок диаграммы. Применим наши новые знания:
import numpy as np import matplotlib.pyplot as plt import matplotlib # задаем размер шрифта matplotlib.rcParams.update('font.size': 12>) rg = np.random.Generator(np.random.PCG64(11)) x = np.arange(6) y = rg.poisson(149, x.size) yerr = [ 0.7*np.sqrt(y), 1.2*np.sqrt(y) ] plt.errorbar(x, y, yerr=yerr, marker='o', linestyle='none', ecolor='k', elinewidth=0.8, capsize=4, capthick=1) # добавляем подписи к осям и заголовок диаграммы plt.xlabel('run number', fontsize=16) plt.ylabel(r'average current ($\mu A$)', fontsize=16) plt.title(r'The $\alpha^\prime$ experiment. Season 2020-2021') # задаем диапазон значений оси y plt.ylim([0, 200]) # оптимизируем поля и расположение объектов plt.tight_layout() plt.show()

В этом примере мы использовали функцию pyplot.tight_layout, которая автоматически подбирает параметры отображения так, чтобы различные элементы не пересекались.
Легенда
При построении нескольких графиков в одних осях полезно добавлять легенду — пояснения к каждой линии. Следующий пример показывает, как это делается с помощью аргументов label и функции pyplot.legend :
import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams.update('font.size': 12>) x = np.linspace(0, 1, 100) f1 = 0.25 - (x - 0.5)**2 f2 = x**3 # указываем в аргументе label содержание легенды plt.plot(x, f1, ':b', label='1st component') plt.plot(x, f2, '--r', label='2nd component') plt.plot(x, f1+f2, 'k', label='total') plt.xlabel(r'$x$', fontsize=16) plt.ylabel(r'$f(x)$', fontsize=16) plt.xlim([0, 1]) plt.ylim([0, 1]) # выводим легенду plt.legend(fontsize=14) plt.tight_layout() plt.show()

Функция pyplot.legend старается расположить легенду так, чтобы она не пересекала графики. Аргумент loc позволяет задать расположение легенды вручную. В большинстве случаев расположение по умолчанию получается удачным. Детали и описание других аргументов смотрите в документации.
Сетка
Сетка во многих случаях облегчает анализ графиков. Включить отображение сетки можно с помощью функции pyplot.grid . Аргумент axis этой функции имеет три возможных значения: x , y и both и определяет оси, вдоль которых будут проведены линии сетки. Управлять свойствами линии сетки можно с помощью именованных аргументов, которые мы рассматривали выше при обсуждении функции pyplot.plot .
В matplotlib поддерживается два типа сеток: основная и дополнительная. Выбор типа сетки выполняется с помощью аргумента which , который может принимать три значения: major , minor и both . По умолчанию используется основная сетка.
Линии сетки привязаны к отметкам на осях. Чтобы работать с дополнительной сеткой необходимо сначала включить вспомогательные отметки на осях (которые по умолчанию отключены и к которым привязаны линии дополнительной сетки) с помощью функции pyplot.minorticks_on . Приведем пример:
import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams.update('font.size': 12>) x = np.linspace(-1, 1, 250) plt.plot(x, x, label=r'$x$') plt.plot(x, x**2, label=r'$x^2$') plt.plot(x, x**3, label=r'$x^3$') plt.plot(x, np.cbrt(x), label=r'$x^$') plt.legend(fontsize=16) # включаем дополнительные отметки на осях plt.minorticks_on() plt.xlabel(r'$x$', fontsize=16) plt.xlim([-1., 1.]) plt.ylim([-1., 1.]) # включаем основную сетку plt.grid(which='major') # включаем дополнительную сетку plt.grid(which='minor', linestyle=':') plt.tight_layout() plt.show()

Логарифмический масштаб
Функции pyplot.semilogy и pyplot.semilogx выполняют переключение между линейным и логарифмическим масштабами осей. В некоторых случаях логарифмический масштаб позволяет отобразить особенности зависимостей, которые не видны в линейном масштабе. Вот так выглядят графики экспоненциальных функций в линейном масштабе:

plt.semilogy()
делает график гораздо более информативным:

Теперь мы видим поведение функций во всем динамическом диапазоне, занимающем 12 порядков.
Произвольные отметки на осях
Вернемся к первому примеру, в котором мы строили графики синуса и косинуса. Сделаем так, чтобы на горизонтальной оси отметки соответствовали различным долям числа pi и имели соответствующие подписи:

Метки на горизонтальной оси были заданы с помощью функции pyplot.xticks :
plt.xticks( np.linspace(-np.pi, np.pi, 9), [r'$-\pi$', r'$-3\pi/4$', r'$-\pi/2$', r'$-\pi/4$', r'$0$', r'$\pi/4$', r'$+\pi/2$', r'$3\pi/4$', r'$+\pi$'])
Модуль pyplot.ticker содержит более продвинутые инструменты для управления отметками на осях. Подробности смотрите в документации.
Размер изображения
До сих пор мы строили графики в одном окне, размер которого был задан по умолчанию. За кадром matplotlib создавал объект типа Figure, который определяет размер окна и содержит все остальные элементы. Кроме того, автоматически создавался объект типа Axis. Подробнее работа с этими объектами будет рассмотрена ниже. Сейчас же мы рассмотрим функцию pyplot.figure , которая позволяет создавать новые объекты типа Figure и переключаться между уже созданными объектами.
Функция pyplot.figure может принимать множество аргументов. Вот основные:
- num : int или str — уникальный идентификатор объекта типа. Если задан новый идентификатор, то создается новый объект и он становится активным. В случае, если передан идентификатор уже существующего объекта, то этот объект возвращается и становится активным
- /media//media/figsize : (float, float) — размер изображения в дюймах
- dpi : float — разрешение в количестве точек на дюйм
Описание других параметров функции pyplot.figure можно найти в документации. Используем эту функцию и функцию pyplot.axis чтобы улучшить наш пример с построением степенных функций:

Мы добавили две строки по сравнению с прошлой версией:
fig = plt.figure(/media//media/figsize=(6, 6)) # . plt.axis('equal')
Функция pyplot.axis позволяет задавать некоторые свойства осей. Ее вызов с параметром ‘equal’ делает одинаковыми масштабы вертикальной и горизонтальной осей, что кажется хорошей идеей в этом примере. Функция pyplot.axis возвращает кортеж из четырех значений xmin, xmax, ymin, ymax , соответствующих границам диапазонов значений осей.
Некоторые другие способы использования функции pyplot.axis :
- Кортеж из четырех float задаст новые границы диапазонов значений осей
- Строка ‘off’ выключит отображение линий и меток осей
Гистограммы
Обратимся теперь к другим типам диаграмм. Функция pyplot.hist строит гистограмму по набору значений:
import numpy as np import matplotlib.pyplot as plt rg = np.random.Generator(np.random.PCG64(5)) data = rg.poisson(145, 10000) plt.hist(data, bins=40) # для краткости мы опускаем код для настройки осей, сетки и т.д.

Аргумент bins задает количество бинов гистограммы. По умолчанию используется значение 10. Если вместо целого числа в аргумент bins передать кортеж значений, то они будут использованы для задания границ бинов. Таким образом можно построить гистограмму с произвольным разбиением.
Некоторые другие аргументы функции pyplot.hist :
- range : (float, float) — диапазон значений, в котором строится гистограмма. Значения за пределами заданного диапазона игнорируются.
- density : bool . При значении True будет построена гистограмма, соответствующая плотности вероятности, так что площадь гистограммы будет равна единице.
- weights : список float значений того же размера, что и набор данных. Определяет вес каждого значения при построении гистограммы.
- histtype : str . может принимать значения . Определяет тип отрисовки гистограммы.
В качестве первого аргумента можно передать кортеж наборов значений. Для каждого из них будет построена гистограмма. Аргумент stacked со значением True позволяет строить сумму гистограмм для кортежа наборов. Покажем несколько примеров:

rg = np.random.Generator(np.random.PCG64(5)) data1 = rg.poisson(145, 10000) data2 = rg.poisson(140, 2000) # левая гистограмма plt.hist([data1, data2], bins=40) # центральная гистограмма plt.hist([data1, data2], bins=40, histtype='step') # правая гистограмма plt.hist([data1, data2], bins=40, stacked=True)
В физике гистограммы часто представляют в виде набора значений с ошибками, предполагая при этом, что количество событий в каждом бине является случайной величиной, подчиняющейся биномиальному распределению. В пределе больших значений флуктуации количества событий в бине могут быть описаны распределением Пуассона, так что характерная величина флуктуации определяется корнем из числа событий. Библиотека matplotlib не имеет инструмента для такого представления данных, однако его легко получить с помощью комбинации numpy.histogram и pyplot.errorbar :
def poisson_hist(data, bins=60, lims=None): """ Гистограмма в виде набора значений с ошибками """ hist, bins = np.histogram(data, bins=bins, range=lims) bins = 0.5 * (bins[1:] + bins[:-1]) return (bins, hist, np.sqrt(hist)) rg = np.random.Generator(np.random.PCG64(5)) data = rg.poisson(145, 10000) x, y, yerr = poisson_hist(data, bins=40, lims=(100, 190)) plt.errorbar(x, y, yerr=yerr, marker='o', markersize=4, linestyle='none', ecolor='k', elinewidth=0.8, capsize=3, capthick=1)

Диаграммы рассеяния
Распределение событий по двум измерениям удобно визуализировать с помощью диаграммы рассеяния:
rg = np.random.Generator(np.random.PCG64(5)) means = (0.5, 0.9) covar = [ [1., 0.6], [0.6, 1.] ] data = rg.multivariate_normal(means, covar, 5000) plt.scatter(data[:,0], data[:,1], marker='o', s=1)

Каждой паре значений в наборе данных соответствует одна точка на диаграмме. Несмотря на свою простоту, диаграмма рассеяния позволяет во многих случаях наглядно представлять двумерные данные. Функция pyplot.scatter позволяет визуализировать и данные более высокой размерности: размер и цвет маркера могут быть заданы для каждой точки отдельно:
rg = np.random.Generator(np.random.PCG64(4)) data = rg.uniform(-1, 1, (50, 2)) col = np.arctan2(data[:, 1], data[:, 0]) size = 100*np.sum(data**2, axis=1) plt.scatter(data[:,0], data[:,1], marker='o', s=size, c=col)

Цветовую палитру можно задать с помощью аргумента cmap . Подробности и описание других аргументов функции pyplot.scatter можно найти в документации.
Контурные диаграммы
Контурные диаграммы позволяют визуализировать функции двух переменных:
from scipy import stats means = (0.5, 0.9) covar = [ [1., 0.6], [0.6, 1.] ] mvn = stats.multivariate_normal(means, covar) x, y = np.meshgrid( np.linspace(-3, 3, 80), np.linspace(-2, 4, 80) ) data = np.dstack((x, y)) # левая диаграмма — без заливки цветом plt.contour(x, y, mvn.pdf(data), levels=10) # правая диаграмма — с заливкой цветом plt.contourf(x, y, mvn.pdf(data), levels=10)

Аргумент levels задает количество контуров. По умолчанию контуры отрисовываются равномерно между максимальным и минимальным значениями. В аргумент levels также можно передать список уровней, на которых следует провести контуры.
Обратите внимание на использование функций numpy.meshgrid и numpy.dstack в этом примере.
Контурную диаграмму можно дополнить цветовой полосой colorbar , вызвав функцию pyplot.colorbar :
cs = plt.contourf(x, y, mvn.pdf(data), levels=15, cmap=matplotlib.cm.magma_r) cbar = plt.colorbar(cs)

Более подробное описание функций plt.contour и plt.contourf смотрите в документации.
Расположение нескольких осей в одном окне
В одном окне (объекте Figure ) можно разместить несколько осей (объектов axis.Axis ). Функция pyplot.subplots создает объект Figure , содержащий регулярную сетку объектов axis.Axis :
import numpy as np from scipy import stats import matplotlib.pyplot as plt fig, axes = plt.subplots(ncols=3, nrows=2, /media//media/figsize=(12, 8)) x = np.linspace(0.01, 25, 250) for idx, row in enumerate(axes): for jdx, ax in enumerate(row): ndf = idx * 3 + jdx + 1 y = stats.chi2.pdf(x, ndf) ax.plot(x, y, label=fr'$\chi^2_ndf=ndf>>>(x)$') ax.set_xlabel(r'$x$', fontsize=16) ax.set_ylim([0, 1.05*y.max()]) ax.minorticks_on() ax.legend(fontsize=16) ax.grid(which='major') ax.grid(which='minor', linestyle=':') fig.tight_layout() plt.show()

Количество строк и столбцов, по которым располагаются различные оси, задаются с помощью параметров nrows и ncols , соответственно. Функция pyplot.subplots возвращает объект Figure и двумерный список осей axis.Axis . Обратите внимание на то, что вместо вызовов функций модуля pyplot в этом примере использовались вызовы методов классов Figure и axis.Axis .
В последнем примере горизонтальная ось во всех графиках имеет один и тот же диапазон. Аргумент sharex функции pyplot.subplots позволяет убрать дублирование отрисовки осей в таких случаях:
fig, axes = plt.subplots(ncols=3, nrows=2, /media//media/figsize=(12, 8), sharex=True) # . for idx, row in enumerate(axes): for jdx, ax in enumerate(row): # . if idx: ax.set_xlabel(r'$x$', fontsize=16)

Существует аналогичный параметр sharey для вертикальной оси.
Более гибкие возможности регулярного расположения осей предоставляет функция pyplot.subplot. Мы не будем рассматривать эту функцию и ограничимся лишь ее упоминанием.
Функция pyplot.axes позволяет добавлять новые оси в текущем окне в произвольном месте:
import numpy as np import matplotlib.pyplot as plt exno = 26 rg = np.random.Generator(np.random.PCG64(5)) x1 = rg.exponential(10, 5000) x2 = rg.normal(10, 0.1, 100) # Строим основную гистограмму plt.hist([x1, x2], bins=150, range=(0, 60), stacked=True) plt.minorticks_on() plt.xlim((0, 60)) plt.grid(which='major') plt.grid(which='minor', linestyle=':') # Строим вторую гистограмму в отдельных осях plt.axes([.5, .5, .4, .4]) plt.hist([x1, x2], bins=100, stacked=True, range=(9, 11)) plt.grid(which='major') plt.tight_layout() # сохраняем диаграмму в файл plt.savefig('histograms.png') plt.show()

В этом примере была использована функция pyplot.savefig , сохраняющая содержимое текущего окна в файл в векторном или растровом формате. Формат задается с помощью аргумента format или автоматически определяется из имени файла (как в примере выше). Набор доступных форматов зависит от окружения, однако в большинстве случаев можно использовать такие форматы как png , jpeg , pdf , svg и eps .
Резюме
Предметом изучения в этом разделе был модуль pyplot библиотеки matplotlib , содержащий инструменты для построения различных диаграмм. Были рассмотрены:
- функции для построения диаграмм pyplot.plot , pyplot.errorbar . pyplot.hist , pyplot.scatter , pyplot.contour и pyplot.contourf ;
- средства настройки свойств линий и маркеров;
- средства настройки координатных осей: подписи, размер шрифта, координатная сетка, произвольные метки др.;
- инструмены для расположения нескольких координатных осей в одном окне.
Рассмотренные инструменты далеко не исчерпывают возможности библиотеки matplotlib , однако их должно быть достаточно в большинстве случаев для визуализации данных. Мы рекомендуем заинтересованному читалелю изучить список источников, в которых можно найти много дополнительной информации.
Источники
- matplotlib.pyplot
- Pyplot tutorial
- Colormaps
- Scipy Lecture Notes
- Введение
- Настройка рабочей среды
- Язык C++
- Язык Python
- Основы синтаксиса языка python
- Строки
- Стандартные модули python, часть I
- ООП в python
- Стандартные модули II
- Итераторы и генераторы
- Вычисления с библиотекой numpy
- Визуализация данных с matplotlib
Визуализация в Python


- Другой пример — scatter (где точки не соединяются прямыми линиями), с указанием точек (x1,y1),(x2,y2),(x3,y3)…
x = np.linspace(0, 5, 50) # создаем массив из 100 чисел float от 0 до 5 с равномернов шагом y = x*(x - 2)*(x - 4) plt.figure(figsize=(8,4)) # можно указать явно ширину и высоту графика (строчка не обязательна) plt.scatter(x, y, label='line_1') plt.legend() # показывать легенду plt.grid(linewidth=1) # включить отрисовку сетки c определенными параметрами plt.yticks() plt.xticks() plt.xlabel('ось абсцисс') plt.ylabel('ось ординат');

- Гистограмма — график, показывающий распределение какой-либо величины, встречающуюся в данном объеме значений. По другому, график показыват сколько раз встречается из выборки каждое значение в ней. Построим гистограммы с помощью разных библиотек.
Один из главных параметров bins — обратная величина к ширине столбцов на графике
df['wage'].hist(figsize=(6, 4), bins=100);

sns.distplot(df['wage'], bins=10);

Можно сразу построить несколько гистограмм, относящихся к разным столбцам данных:
features = ['wage', 'exper'] df[features].hist(figsize=(10, 4), bins=60);

- CountPlot — столбчатая диаграмма, чаще всего используется для категориальных признаков в данных. Показывает, сколько трочек в df имеют каждое из выбранного значения категориального признака.
sns.countplot(x='female', data=df);

sns.countplot(y='female', data=df);

Приведем пример для столбца look относительно параметра female в DataFrame df
sns.countplot(x='female', hue='looks', data=df);

На следующем примере покажем, как нарисовать несколько графиков на одной картинке: axes — части графика. axes[0] — левая часть, а axes[1] — правая. Аналогично можно создать сетку 2х2 для 4х графиков (но для 4х графиков нужно указывать уже 2 координаты, например, ax=axis[1][1]).
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 4)) sns.countplot(x='female', data=df, ax=axes[0]); sns.countplot(x='looks', data=df, ax=axes[1]);

- Круговая диаграмма отлично показывает соотношение частей:
plt.pie(df.groupby('female')['wage'].count()); # круговая диаграмми (pie)

- Ящик с усами, или boxplot Box plot состоит из коробки (поэтому он и называется box plot), усиков и точек. Коробка показывает интерквартильный размах распределения, то есть соответственно 25% (Q1) и 75% (Q3) перцентили.
Черта внутри коробки обозначает медиану распределения.
Усы отображают весь разброс точек кроме выбросов, то есть минимальные и максимальные значения, которые попадают в промежуток (Q1 — 1.5IQR, Q3 + 1.5IQR), где IQR = Q3 — Q1 — интерквартильный размах.
Точками на графике обозначаются выбросы (outliers) — те значения, которые не вписываются в промежуток значений, заданный усами графика.
sns.boxplot(x='wage', data=df);

_, axes = plt.subplots(1, 2, sharey=True, figsize=(6, 4)) sns.boxplot(data=df['wage'], ax=axes[0]); sns.violinplot(data=df['wage'], ax=axes[1]);

Для большего понимания посмотреть на картинку из Wikipedia:

- joint plot: Для того, чтобы подробнее посмотреть на взаимосвязь двух численных признаков, есть еще и joint plot — это гибрид scatter plot и histogram. Посмотрим на то, как связаны между собой wage и exper.
sns.jointplot(x='wage', y='exper', data=df, kind='scatter');

sns.jointplot('exper', 'wage', data=df, kind="kde", color="r");

После всего вышесказанного, нужно отметить, что можно делать некоторые операции над DataFrame, и уже к ним применять метод .plot(…).
df.groupby('looks').wage.sum().plot(kind='bar', rot=75, color='green');

df[features].plot(kind='density', subplots=True, layout=(1, 2), sharex=False, figsize=(10, 4));

3D графики
from mpl_toolkits.mplot3d import Axes3D from sklearn import datasets from sklearn.decomposition import PCA # import some data to play with iris = datasets.load_iris() X = iris.data[:, :2] # we only take the first two features. y = iris.target x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5 y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5 X_reduced = PCA(n_components=3).fit_transform(iris.data) # To getter a better understanding of interaction of the dimensions # plot the first three PCA dimensions fig = plt.figure(1, figsize=(8, 6)) ax = Axes3D(fig, elev=-150, azim=110) ax.scatter(X_reduced[:, 0], X_reduced[:, 1], X_reduced[:, 2], c=y, cmap=plt.cm.Set1, edgecolor='k', s=40) ax.set_title("First three PCA directions") ax.set_xlabel("1st eigenvector") ax.w_xaxis.set_ticklabels([]) ax.set_ylabel("2nd eigenvector") ax.w_yaxis.set_ticklabels([]) ax.set_zlabel("3rd eigenvector") ax.w_zaxis.set_ticklabels([]) plt.show()

Создание анимации
import matplotlib.animation as animation from matplotlib.animation import PillowWriter import matplotlib.lines as mlines from sklearn.datasets import load_iris from sklearn.decomposition import PCA from sklearn.model_selection import train_test_split def newline(p1, p2, color=None): # функция отрисовки линии #function kredits to: https://fooobar.com/questions/626491/how-to-draw-a-line-with-matplotlib ax = plt.gca() xmin, xmax = ax.get_xbound() if(p2[0] == p1[0]): xmin = xmax = p1[0] ymin, ymax = ax.get_ybound() else: ymax = p1[1]+(p2[1]-p1[1])/(p2[0]-p1[0])*(xmax-p1[0]) ymin = p1[1]+(p2[1]-p1[1])/(p2[0]-p1[0])*(xmin-p1[0]) l = mlines.Line2D([xmin,xmax], [ymin,ymax], color=color) ax.add_line(l) return l def one_image(w, X, Y): # фунцкия отрисовки одного кадра axes = plt.gca() axes.set_xlim([-4,4]) axes.set_ylim([-1.5,1.5]) d1 = -1:'green', 1:'red'> im = plt.scatter(X[:,0], X[:,1], c=[d1[y] for y in Y]) im = newline([0,-w[2]/w[1]],[-w[2]/w[0],0], 'blue') return im # блок подготовки данных iris = load_iris() X = iris.data Y = iris.target pca = PCA(n_components=2) X = pca.fit_transform(X) Y = (Y == 2).astype(int)*2-1 # [0,1,2] --> [False,False,True] --> [0,1,1] --> [0,0,2] --> [-1,1,1] X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.4, random_state=2020) history_w = np.array([[ 1.40100620e-02, 3.82414425e-02, 9.29992169e-03], [ 9.34759319e-02, 1.38405275e-02, -2.07000784e-02], [ 1.77059209e-01, 2.08938874e-02, -5.07000782e-02], [ 2.57582976e-01, 1.13119698e-02, -8.07000777e-02], [ 2.57845336e-01, 3.30044268e-02, -1.10700077e-01], [ 2.48875308e-01, 4.34713607e-02, -1.40700076e-01], [ 2.10330535e-01, 2.29165461e-02, -1.70700074e-01], [ 2.88030722e-01, 1.60452308e-02, -2.00700073e-01], [ 3.65670311e-01, 6.38421381e-04, -2.30700071e-01], [ 4.22698556e-01, 4.13726013e-03, -2.00700068e-01], [ 3.91374597e-01, -2.71359690e-03, -2.30700066e-01], [ 4.56157722e-01, -9.23192424e-03, -2.00700064e-01], [ 4.56157718e-01, -9.23192415e-03, -2.00700062e-01], [ 4.56157713e-01, -9.23192405e-03, -2.00700060e-01], [ 5.15303640e-01, -1.46237611e-02, -1.70700058e-01], [ 5.15303635e-01, -1.46237609e-02, -1.70700056e-01], [ 5.15303630e-01, -1.46237608e-02, -1.70700055e-01], [ 5.15303625e-01, -1.46237607e-02, -1.70700053e-01], [ 5.15303619e-01, -1.46237605e-02, -1.70700051e-01], [ 5.51273647e-01, -3.28065062e-02, -1.40700049e-01], [ 5.51273642e-01, -3.28065059e-02, -1.40700048e-01], [ 5.51273636e-01, -3.28065055e-02, -1.40700047e-01], [ 5.66508857e-01, 5.17263051e-03, -1.70700045e-01], [ 5.66508852e-01, 5.17263046e-03, -1.70700044e-01], [ 5.66508846e-01, 5.17263040e-03, -1.70700042e-01], [ 5.66508840e-01, 5.17263035e-03, -1.70700040e-01], [ 5.48868641e-01, 1.97012529e-02, -2.00700038e-01], [ 5.48868636e-01, 1.97012527e-02, -2.00700036e-01], [ 5.48868630e-01, 1.97012525e-02, -2.00700034e-01], [ 5.54086386e-01, 2.73468786e-02, -2.30700032e-01], [ 5.96543457e-01, 1.00993879e-02, -2.00700030e-01], [ 5.96543451e-01, 1.00993878e-02, -2.00700028e-01], [ 5.96543445e-01, 1.00993877e-02, -2.00700026e-01], [ 6.38206423e-01, 3.96740775e-03, -1.70700024e-01], [ 6.38206417e-01, 3.96740771e-03, -1.70700022e-01], [ 6.11201179e-01, -5.88772655e-03, -2.00700021e-01], [ 6.52906839e-01, -1.43675546e-02, -1.70700019e-01], [ 6.52906832e-01, -1.43675545e-02, -1.70700017e-01], [ 6.52906826e-01, -1.43675543e-02, -1.70700015e-01], [ 6.42197374e-01, 7.79748602e-04, -2.00700014e-01], [ 6.03251852e-01, 1.06133678e-02, -2.30700012e-01], [ 6.03251846e-01, 1.06133677e-02, -2.30700009e-01], [ 6.05295634e-01, 3.17685316e-02, -2.60700007e-01], [ 6.05295628e-01, 3.17685313e-02, -2.60700004e-01], [ 6.05295622e-01, 3.17685310e-02, -2.60700002e-01], [ 5.85487103e-01, 4.23576206e-02, -2.90699999e-01], [ 5.85487097e-01, 4.23576202e-02, -2.90699996e-01], [ 5.57651268e-01, 2.83422349e-02, -3.20699993e-01], [ 5.53558401e-01, 3.77632078e-02, -3.50699990e-01], [ 5.12157603e-01, 5.03918360e-02, -3.80699987e-01]]) fig = plt.figure() ims = [] # набиваем в этот список кадры с помощью цикла for i in range(50): im = one_image(history_w[i], X_train, Y_train) ims.append([im]) ani = animation.ArtistAnimation(fig, ims, interval=20, blit=True, # используем волшебную команду repeat_delay=500) writer = PillowWriter(fps=20) # устанавливаем фпс ani.save("my_demo.gif", writer='imagemagick') # сохраняем
MovieWriter imagemagick unavailable; trying to use instead.
Домашнее задание:
- ДЗ по 2м последним лабам (15 — pandas, 16 — визуализация): Нужно взять данные отсюда: https://github.com/Laggg/data–for–students (flight_delays.csv)
- для каждой задачи получить ответ на вопрос через pandas и визуализировать его любым подходящим способом (у всех графиков должна быть легенда, подписаны оси):
- доля всех задержек ко всем вылетам
- найти зависимость количества задержек от длины пути, который предстоит пролететь самолету
- топ 5 направлений, для которых чаще всего происходят задержки
- в какие времена года чаще всего происходят задержки рейсов
- найти топ 10 самых хороших перевозчиков, которые реже всего задерживают свои рейсы
- найти топ 10 самых безответственных аэропортов, в которых чаще всего происходят задержки
- найти необычную зависимость количества задержек от имеющихся данных
import pandas as pd pd.read_csv('flight_delays.csv').head(10)
Month DayofMonth DayOfWeek DepTime UniqueCarrier Origin Dest Distance dep_delayed_15min 0 c-8 c-21 c-7 1934 AA ATL DFW 732 N 1 c-4 c-20 c-3 1548 US PIT MCO 834 N 2 c-9 c-2 c-5 1422 XE RDU CLE 416 N 3 c-11 c-25 c-6 1015 OO DEN MEM 872 N 4 c-10 c-7 c-6 1828 WN MDW OMA 423 Y 5 c-8 c-3 c-4 1918 NW MEM MCO 683 N 6 c-1 c-27 c-4 754 DL PBI LGA 1035 N 7 c-4 c-29 c-6 635 OH MSP CVG 596 N 8 c-7 c-28 c-5 735 AA ONT DFW 1189 N 9 c-6 c-20 c-2 2029 OO DEN PSC 853 N Очень полезные ссылки:
- https://habr.com/ru/post/468295/
- https://habr.com/ru/company/ods/blog/323210/
Сайт построен с использованием Pelican. За основу оформления взята тема от Smashing Magazine. Исходные тексты программ, приведённые на этом сайте, распространяются под лицензией GPLv3, все остальные материалы сайта распространяются под лицензией CC-BY.