Как построить scatter plot в python
Перейти к содержимому

Как построить scatter plot в python

  • автор:

Matplotlib. Урок 4.2. Визуализация данных. Ступенчатый, стековый, точечный график и другие

Follow us on Google Plus Follow us on rss

В этому уроке рассмотрим на примерах работу со ступенчатым, стековым, 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 комментарий

      1. Узбек 18.09.2020 Ссайт реально хороший.Ребята все чётко объяснили.Вопросов нет

      Matplotlib: как раскрасить диаграмму рассеяния по значению

      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 по значению

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

      Например, вместо этого мы могли бы указать «Зеленые» в качестве цветовой карты:

      plt.scatter (df.x, df.y, s=200, c=df.z, cmap='Greens') 

      Диаграмма рассеяния Matplotlib с cmap

      По умолчанию маркеры с большими значениями аргумента c затемняются темнее, но вы можете изменить это, просто добавив _r к имени cmap:

      plt.scatter (df.x, df.y, s=200, c=df.z, cmap='Greens_r') 

      Обратный масштаб цветовой карты Matplotlib

      Пример 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() 

      Диаграмма рассеяния Matplotlib, окрашенная по категориям

      Вы можете найти больше руководств по 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() 

      В результате получаем

      ex1

      Мы использовали функцию 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() 

      ex2

      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() 

      ex3

      Из последнего примера видно, что если в функцию 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() 

      ex4

      Ошибки можно задавать и для значений по горизонтальной оси:

      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() 

      ex5

      Ошибки измерений могут быть асимметричными. Для их отображения в качестве параметра 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() 

      ex6

      Функция 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() 

      ex7

      Настройки отображения

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

      Диапазон значений осей

      Задавать диапазон значений осей в 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() 

      ex8

      В этом примере мы использовали функцию 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() 

      ex9

      Функция 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() 

      ex10

      Логарифмический масштаб

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

      ex11

      plt.semilogy() 

      делает график гораздо более информативным:

      ex12

      Теперь мы видим поведение функций во всем динамическом диапазоне, занимающем 12 порядков.

      Произвольные отметки на осях

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

      ex13

      Метки на горизонтальной оси были заданы с помощью функции 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 чтобы улучшить наш пример с построением степенных функций:

      ex14

      Мы добавили две строки по сравнению с прошлой версией:

      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) # для краткости мы опускаем код для настройки осей, сетки и т.д. 

      ex15

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

      Некоторые другие аргументы функции pyplot.hist :

      • range : (float, float) — диапазон значений, в котором строится гистограмма. Значения за пределами заданного диапазона игнорируются.
      • density : bool . При значении True будет построена гистограмма, соответствующая плотности вероятности, так что площадь гистограммы будет равна единице.
      • weights : список float значений того же размера, что и набор данных. Определяет вес каждого значения при построении гистограммы.
      • histtype : str . может принимать значения . Определяет тип отрисовки гистограммы.

      В качестве первого аргумента можно передать кортеж наборов значений. Для каждого из них будет построена гистограмма. Аргумент stacked со значением True позволяет строить сумму гистограмм для кортежа наборов. Покажем несколько примеров:

      ex18

      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) 

      ex19

      Диаграммы рассеяния

      Распределение событий по двум измерениям удобно визуализировать с помощью диаграммы рассеяния:

      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) 

      ex20

      Каждой паре значений в наборе данных соответствует одна точка на диаграмме. Несмотря на свою простоту, диаграмма рассеяния позволяет во многих случаях наглядно представлять двумерные данные. Функция 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) 

      ex21

      Цветовую палитру можно задать с помощью аргумента 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) 

      ex22

      Аргумент 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) 

      ex23

      Более подробное описание функций 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() 

      ex24

      Количество строк и столбцов, по которым располагаются различные оси, задаются с помощью параметров 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) 

      ex25

      Существует аналогичный параметр 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() 

      ex26

      В этом примере была использована функция 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

        1. Другой пример — 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('ось ординат'); 

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

        Один из главных параметров 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); 

        1. 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]); 

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

        1. Ящик с усами, или 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:

        1. 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.

        Домашнее задание:

        1. ДЗ по 2м последним лабам (15 — pandas, 16 — визуализация): Нужно взять данные отсюда: https://github.com/Laggg/data–for–students (flight_delays.csv)
        2. для каждой задачи получить ответ на вопрос через 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.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *