1495 lines
49 KiB
Plaintext
1495 lines
49 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<!-- dom:TITLE: Графическая визуализация данных -->\n",
|
||
"# Графическая визуализация данных\n",
|
||
"<!-- dom:AUTHOR: С.В. Лемешевский Email:sergey.lemeshevsky@gmail.com at Институт математики НАН Беларуси -->\n",
|
||
"<!-- Author: --> \n",
|
||
"**С.В. Лемешевский** (email: `sergey.lemeshevsky@gmail.com`), Институт математики НАН Беларуси\n",
|
||
"\n",
|
||
"Date: **Mar 31, 2020**\n",
|
||
"\n",
|
||
"Одной из важных частей в анализе данных является графическое\n",
|
||
"визуализация. Это может быть частью исследовательского процесса —\n",
|
||
"например, чтобы помочь идентифицировать выбросы или необходимые\n",
|
||
"преобразования данных, или как способ генерирования идей для\n",
|
||
"моделей. В Python есть много дополнительных библиотек для создания\n",
|
||
"статических или динамических визуализаций, но мы сосредоточемся в\n",
|
||
"основном на `matplotlib` и библиотеках, которые построены на её\n",
|
||
"основе. \n",
|
||
"\n",
|
||
"Со временем `matplotlib` породила ряд дополнительных наборов инструментов\n",
|
||
"для визуализации данных, которые используют `matplotlib` в качестве\n",
|
||
"«ядра». Одним из таких инструментов является `seaborn`.\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- Common Mako variable and functions -->\n",
|
||
"<!-- -*- coding: utf-8 -*- -->\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Краткий пример использования `matplotlib`\n",
|
||
"<div id=\"visual:matplotlib\"></div>\n",
|
||
"\n",
|
||
"Для импорта библиотеки `matplotlib` будем использовать следующее\n",
|
||
"соглашение:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"%matplotlib inline\n",
|
||
"\n",
|
||
"import matplotlib.pyplot as plt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Ниже приведен пример построения простой прямой:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"data = np.arange(10)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"data"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"plt.plot(data)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Рисунки и подграфики\n",
|
||
"<div id=\"visual:matplotlib:figs_and_subplots\"></div>\n",
|
||
"\n",
|
||
"Графики в `matplotlib` находятся внутри объекта `Figure`. Новый\n",
|
||
"рисунок можно создать с помощью `plt.figure`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig = plt.figure()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"В интерпретаторе IPython будет построено пустое окно, а в блокноте\n",
|
||
"Jupyter ничего не произойдет. Нельзя создавать окно с пустым\n",
|
||
"рисунком. Нужно создать один или несколько подграфиков (subplots),\n",
|
||
"используя функцию `add_subplot`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig.add_subplot(2, 2, 1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Это означает, что рисунок должен быть размером $2 \\times 2$\n",
|
||
"(т.е. содержать максимум 4 графика), и мы выбрали первый из четырех\n",
|
||
"графиков (нумерация начинается с единицы). Можно выбрать следующие 2\n",
|
||
"графика:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"ax2 = fig.add_subplot(2, 2, 2)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"ax3 = fig.add_subplot(2, 2, 3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Если выполнить команду построения графика, например, `plt.plot([1.5, 3.5, -2, 1.6])`,\n",
|
||
"вывод будет осуществляться в последний график последнего созданного\n",
|
||
"рисунка. Например, выполнение команды"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"plt.plot(np.random.randn(50).cumsum(), 'k--')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Выражение `'k--'` задает стиль линии: черная штриховая линия. \n",
|
||
"Метод `fig.add_subplot` возвращает объект `AxesSubplot`, в который\n",
|
||
"можно напрямую выводить график:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"_ = ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Полный каталог типов графиков можно найти на сайте <https://matplotlib.org/>.\n",
|
||
"\n",
|
||
"Как вы заметили представленные выше команды, выполняемые в отдельных\n",
|
||
"ячейках, в блокноте Jupyter не работают. Для того чтобы строить\n",
|
||
"подграфики в Jupyter нужно все команды выполнять в одной ячейке:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig = plt.figure()\n",
|
||
"fig.add_subplot(2, 2, 1)\n",
|
||
"ax1 = fig.add_subplot(2, 2, 2)\n",
|
||
"ax2 = fig.add_subplot(2, 2, 3)\n",
|
||
"plt.plot([1.5, 3.5, -2, 1.6])\n",
|
||
"_ = ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)\n",
|
||
"ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Цвет, маркеры и стили линий\n",
|
||
"<div id=\"visual:matplotlib:colors\"></div>\n",
|
||
"\n",
|
||
"Основная функция `plot` библиотеки `matplotlib` принимает массивы\n",
|
||
"координат `x` и `y` и (опционально) строку, задающую цвет и стиль\n",
|
||
"линии. Например, для того чтобы построить зависимость `y` от `x`\n",
|
||
"зелеными штрихами, необходимо выполнить:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" ax.plot(x, y, 'g--')\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Таким образом, мы задали и цвет и стиль линии в виде строки. На\n",
|
||
"практике при программном создании графиков использование строк не\n",
|
||
"удобно. Такой же график можно построить с помощью команды:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" ax.plot(x, y, linestyle='--', color='g')\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Графики могут иметь также маркеры для выделения точек данных. Так как\n",
|
||
"`matplotlib` создает непрерывные линии, интерполируя значения между\n",
|
||
"заданными точками, может быть не ясно, где находятся заданные\n",
|
||
"значения. Маркеры могут быть частью строки, задающей стиль линии:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"from numpy.random import randn"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"plt.plot(randn(30).cumsum(), 'ko--')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Это же можно было записать более явно:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Как видно, между последовательными точками строится линейная\n",
|
||
"интерполяция. Это поведение можно изменить с помощью параметра\n",
|
||
"`drawstyle`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"data = np.random.randn(30).cumsum()\n",
|
||
"plt.plot(data, 'k--', label='Default')\n",
|
||
"plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')\n",
|
||
"plt.legend(loc='best')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Подписи к осям, масштаб и легенда\n",
|
||
"<div id=\"visual:matplotlib:ticks\"></div>\n",
|
||
"\n",
|
||
"Для иллюстрации настройки графиков создадим простой рисунок и\n",
|
||
"отобразим график случайного блуждания:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig = plt.figure()\n",
|
||
"ax = fig.add_subplot(1, 1, 1)\n",
|
||
"ax.plot(np.random.randn(1000).cumsum())"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Для изменения подписей на оси $x$ воспользуемся методами `set_xticks`\n",
|
||
"и `set_xticklables`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig = plt.figure()\n",
|
||
"ax = fig.add_subplot(1, 1, 1)\n",
|
||
"ax.plot(np.random.randn(1000).cumsum())\n",
|
||
"ticks = ax.set_xticks([0, 250, 500, 750, 1000])\n",
|
||
"labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Параметр `rotation` поворачивает метки надписей на оси $x$ на 30\n",
|
||
"градусов. И, наконец, зададим название графика и метку для оси $x$ с\n",
|
||
"помощью методов `set_title` и `set_xlabel`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig = plt.figure()\n",
|
||
"ax = fig.add_subplot(1, 1, 1)\n",
|
||
"ax.plot(np.random.randn(1000).cumsum())\n",
|
||
"ticks = ax.set_xticks([0, 250, 500, 750, 1000])\n",
|
||
"labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small')\n",
|
||
"ax.set_title('Первый график matplotlib')\n",
|
||
"ax.set_xlabel('Шаги')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Модификация оси $y$ осуществляется точно также, только нужно заменить\n",
|
||
"`x` на `y` в приведенном выше коде. У класса осей есть метод `set`,\n",
|
||
"который допускает пакетную настройку свойств графика. В предыдущем \n",
|
||
"примере можно было также написать:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" props = {\n",
|
||
" 'title': 'Первый график matplotlib',\n",
|
||
" 'xlabel': 'Шаги\n",
|
||
" }\n",
|
||
" ax.set(**props)\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Для вывода легенды графика есть несколько способов. Простейший\n",
|
||
"заключается в передаче аргумента `label` при построении графиков:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig = plt.figure(); ax = fig.add_subplot(1, 1, 1)\n",
|
||
"ax.plot(randn(1000).cumsum(), 'k', label='one')\n",
|
||
"ax.plot(randn(1000).cumsum(), 'k--', label='two')\n",
|
||
"ax.plot(randn(1000).cumsum(), 'k.', label='three')\n",
|
||
"ax.legend(loc='best')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Сохранение рисунков в файл\n",
|
||
"<div id=\"visual:matplotlib:saving\"></div>\n",
|
||
"\n",
|
||
"Можно сохранить активный рисунок в файл с помощью метода\n",
|
||
"`plt.savefig`. Например, чтобы сохранить рисунок в формате SVG\n",
|
||
"достаточно набрать:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" plt.savefig('figpath.svg')\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Тип файла определяется расширением. Есть пара важных параметров:\n",
|
||
"`dpi`, который задает разрешение рисунка (точек на дюйм),\n",
|
||
"`bbox_inches`, который может обрезать пустое пространство вокруг\n",
|
||
"рисунка. Например, чтобы сохранить тот же график в формате PNG с\n",
|
||
"разрешением 400 DPI, нудно выполнить:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" plt.savefig('figpath.png', dpi=400, bbox_inches='tight')\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Функция `savefig` сохраняет не только на диск. Она может записывать\n",
|
||
"график в любой файлоподобный объект, например в `BytesIO`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" from io import BytesIO\n",
|
||
" buffer = BytesIO()\n",
|
||
" plt.savefig(buffer)\n",
|
||
" plot_data = buffer.getvalue()\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Таблица 1 : Метод `savefig`: параметры\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\"> Параметр </th> <th align=\"left\"> Описание </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>fname</code> </td> <td align=\"left\"> Строка, содержащая путь к файлу или файлоподобный объект Python. Формат рисунка определяется расширением файла </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>dpi</code> </td> <td align=\"left\"> Разрешение рисунка в точках на дюйм. По умолчанию 100 </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>facecolor</code>, <code>edgecolor</code> </td> <td align=\"left\"> Цвет фона рисунка вне графика. По умолчанию <code>w</code> (белый) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>format</code> </td> <td align=\"left\"> Явное задание формата файла </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>bbox_inches</code> </td> <td align=\"left\"> Часть рисунка для сохранения. Если задано <code>'tight'</code>, 2будет попытка обрезать пустое пространство вокруг </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"visual\" -->\n",
|
||
"<!-- doconce-section-nickname: \"matplotlib\" -->\n",
|
||
"<!-- End: -->\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"\n",
|
||
"# Построение графиков с помощью `pandas` и `seaborn`\n",
|
||
"<div id=\"visual:plt-with-pandas\"></div>\n",
|
||
"\n",
|
||
"Библиотека `matplotlib` может быть инструментом довольно низкого\n",
|
||
"уровня. График собирается из его базовых компонентов: отображения\n",
|
||
"данных (т.е. тип графика: линия, полоса, прямоугольник, разброс,\n",
|
||
"контур и т.д.), легенды, заголовка, меток и других аннотаций. В\n",
|
||
"библиотеке `pandas` мы можем получить множество столбцов данных, а\n",
|
||
"также метки строк и столбцов. В `pandas` имеются встроенные методы,\n",
|
||
"которые упрощают визуализацию объектов `DataFrame` и `Series`. Еще\n",
|
||
"одна библиотека для статистических графиков — `seaborn`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"import pandas as pd"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Линейные графики\n",
|
||
"<div id=\"visual:plt-with-pandas:line\"></div>\n",
|
||
"\n",
|
||
"Объекты `Series` и `DataFrame` имеют метод `plot` для создания базовых\n",
|
||
"типов графиков. По умолчанию `plot()` создает линейные графики"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"s = pd.Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10))\n",
|
||
"s.plot()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Индекс объекта `Series` передается в `plot` библиотеки `matplotlib`\n",
|
||
"для оси $x$. При этом такое поведение можно отключить с помощью\n",
|
||
"параметра `use_index = False`. В таблице\n",
|
||
"[visual:plt-with-pandas:tbl:1](#visual:plt-with-pandas:tbl:1) дается полный список\n",
|
||
"параметров функции `Series.plot`.\n",
|
||
"\n",
|
||
"Большинство графических методов `pandas` принимают опциональный\n",
|
||
"параметр `ax`, который может являться объектом `subplot`. Это\n",
|
||
"позволяет размещать подграфики на сетке.\n",
|
||
"\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Таблица 2 : Параметры метода `Series.plot` <div id=\"visual:plt-with-pandas:tbl:1\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\"> Параметр </th> <th align=\"left\"> Описани </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>label</code> </td> <td align=\"left\"> Метка для легенды </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>ax</code> </td> <td align=\"left\"> Объект <code>subplot</code> из <code>matplotlib</code>, в который выводится график. Если не задан — вывод идет в активный подграфик </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>style</code> </td> <td align=\"left\"> Строка, задающая стиль графика (например, <code>ko--</code>) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>alpha</code> </td> <td align=\"left\"> Прозрачность заполнения графика (от 0 до 1) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>kind</code> </td> <td align=\"left\"> Тип графика. Может быть: 'area' , 'bar' , 'barh' , 'density', 'hist' , 'kde' , 'line' , 'pie' </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>logy</code> </td> <td align=\"left\"> Использовать ли логарифмический масштаб по оси <code>y</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>use_index</code> </td> <td align=\"left\"> Использовать ли объект индекс для меток оси </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>rot</code> </td> <td align=\"left\"> Поворот меток оси </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>xticks</code> </td> <td align=\"left\"> Значения для меток оси <code>x</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>yticks</code> </td> <td align=\"left\"> Значения для меток оси <code>x</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>xlim</code> </td> <td align=\"left\"> Границы по оси <code>x</code> (например, <code>[0, 10]</code>) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>ylim</code> </td> <td align=\"left\"> Границы по оси <code>y</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>grid</code> </td> <td align=\"left\"> Отображать ли сетку по осям (включено по умолчанию) </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Метод `plot` объекта `DataFrame` выводит график для каждого столбца\n",
|
||
"данных в виде линии на одном и том же подграфике, создавая при этом\n",
|
||
"легенду автоматически:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"df = pd.DataFrame(np.random.randn(10, 4).cumsum(0), columns=['A', 'B', 'C', 'D'], index=np.arange(0, 100, 10))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"df.plot()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Атрибут `plot` содержит «семейство» методов для различных типов\n",
|
||
"графиков. Например, `df.plot()` эквивалентно `df.plot.line()`.\n",
|
||
"\n",
|
||
"В `DataFrame` есть несколько параметры, которые обеспечивают некоторую\n",
|
||
"гибкость при обработке столбцов. Например, следует ли разместить их\n",
|
||
"все на одном подграфике или создавать отдельные. В таблице\n",
|
||
"[visual:plt-with-pandas:tbl:2](#visual:plt-with-pandas:tbl:2) представлены такие параметры.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Таблица 3 : Специфичные для `DataFrame` параметры `plot` <div id=\"visual:plt-with-pandas:tbl:2\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\"> Параметр </th> <th align=\"left\"> Описание </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>subplots</code> </td> <td align=\"left\"> Рисовать ли каждый столбец <code>DataFrame</code> в отдельном подграфике </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>sharex</code> </td> <td align=\"left\"> Если <code>subplots=True</code>, использовать ли одну и ту же ось <code>x</code>, связывая метки оси </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>sharey</code> </td> <td align=\"left\"> Если <code>subplots=True</code>, использовать ли одну и ту же ось <code>y</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>figsize</code> </td> <td align=\"left\"> Размер рисунка для создания в виде кортежа </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>title</code> </td> <td align=\"left\"> Заголовок рисунка в виде строки </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>legend</code> </td> <td align=\"left\"> Добавлять ли легенду на рисунок (по умолчанию <code>True</code>) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>sort_columns</code> </td> <td align=\"left\"> Отображать ли столбцы в алфавитном порядке </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Столбчатые диаграммы\n",
|
||
"<div id=\"visual:plt-with-pandas:bar\"></div>\n",
|
||
"\n",
|
||
"Методы `plot.bar()` и `plot.barh()` строят вертикальные и\n",
|
||
"горизонтальные столбчатые диаграммы. В этом случае индексы объектов\n",
|
||
"`Series` и `DataFrame` в качестве меток на оси `x` (`bar`) или `y`\n",
|
||
"(`barh`)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"fig, axes = plt.subplots(2, 1)\n",
|
||
"data = pd.Series(np.random.rand(16), index=list('abcdefghijklmnop'))\n",
|
||
"data.plot.bar(ax=axes[0], color='k', alpha=0.7)\n",
|
||
"data.plot.barh(ax=axes[1], color='k', alpha=0.7)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Параметры `color='k`' и `alpha=0.7` устанавливают цвет графика в\n",
|
||
"черный и частичную прозрачность для заполнения.\n",
|
||
"\n",
|
||
"В `DataFrame` столбчатые диаграммы группируют каждую строку значений\n",
|
||
"вместе в группу столбиков, соответствующих каждому значению в строке:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"df = pd.DataFrame(np.random.rand(6, 4), index=['one', 'two', 'three', 'four', 'five', 'six'], columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"df"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"df.plot.bar()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Обратите внимание на то, что имя столбцов `'Genus'` используется в\n",
|
||
"качестве заголовка легенды. Для создания столбчатых диаграмм с\n",
|
||
"накоплением для `DataFrame` задается параметр `stacked=True`, в\n",
|
||
"результате чего значение в каждой строке будут сгруппировано вместе"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"df.plot.barh(stacked=True, alpha=0.5)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Предположим, что есть набор данных по счетам и чаевым в ресторане, и\n",
|
||
"нам нужно построить столбчатую диаграмму с накоплением, показывающую\n",
|
||
"процентное соотношение точек данных для каждого размера группы в\n",
|
||
"каждый день. Загрузим данные из файла\n",
|
||
"[tips.csv](src-visual/tips.csv.txt) и создадим сводную по дням и размеру вечеринки\n",
|
||
"(количество человек):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"tips = pd.read_csv('src-visual/tips.csv')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"tips.head()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"party_counts = pd.crosstab(tips['day'], tips['size'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"party_counts"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"party_counts = party_counts.loc[:, 2:5]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Теперь нормализуем данные так, чтобы сумма в каждой строке была равна\n",
|
||
"$1$ и построим столбчатую диаграмму:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"party_pcts = party_counts.div(party_counts.sum(1), axis=0)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"party_pcts"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"party_pcts.plot.bar()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Таким образом, видно, что количество участников вечеринок\n",
|
||
"в данном наборе увеличивается в выходные дни.\n",
|
||
"\n",
|
||
"В случае, если требуется агрегировать или суммировать данные перед\n",
|
||
"построением графика, использование пакета `seaborn` может значительно\n",
|
||
"упростить задачу. Давайте посмотрим на процент чаевых в день с помощью\n",
|
||
"библиотеки `seaborn`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import seaborn as sns"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"tips['tip_pct'] = tips['tip']/(tips['total_bill'] - tips['tip'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"tips.head()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.barplot(x='tip_pct', y='day', data=tips, orient='h')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Функция `barplot` библиотеки `seaborn` принимает параметр `data`, который\n",
|
||
"может быть объектом `DataFrame`. Остальные параметры ссылаются на\n",
|
||
"имена столбцов. Поскольку в день имеется несколько наблюдений, то\n",
|
||
"столбцы диаграммы представляют собой среднее значение параметра\n",
|
||
"`tip_pct`. Черные линии, нарисованные на столбцах диаграммы,\n",
|
||
"представляют 95-процентный доверительный интервал (это можно настроить\n",
|
||
"с помощью опционального параметра). \n",
|
||
"\n",
|
||
"Функция `barplot` имеет параметр `hue`, который позволяет разделить\n",
|
||
"отображение по дополнительному категориальному значению:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.barplot(x='tip_pct', y='day', hue='time', data=tips, orient='h')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Гистограммы и графики плотности распределения\n",
|
||
"<div id=\"visual:plt-with-pandas:hist\"></div>\n",
|
||
"\n",
|
||
"*Гистограмма* — это своего рода столбчатая диаграмма, которая дает\n",
|
||
"дискретное отображение частоты значений. Составим гистограмму\n",
|
||
"процентных долей от общего счета, используя метод `plot.hist` объекта\n",
|
||
"`Series`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"tips['tip_pct'].plot.hist(bins=50)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Связанный с гистограммой тип графиков — *график плотности*, \n",
|
||
"который формируется путем вычисления оценки непрерывного распределения\n",
|
||
"вероятности, которое могло бы генерироваться наблюдаемыми данными.\n",
|
||
"Обычная процедура заключается в аппроксимации этого распределение как\n",
|
||
"смеси «ядер», то есть более простых распределений, таких как нормальное\n",
|
||
"распределение. Таким образом, графики под графиками плотности также\n",
|
||
"можно понимать графики оценки плотности ядра\n",
|
||
"(*K*ernel *D*ensity *E*stimate). Функции `plot.kde` и `plot.density`\n",
|
||
"строят график плотности, используя подход KDE:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"tips['tip_pct'].plot.kde()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Библиотека `seaborn` упрощает создание гистограмм и графиков плотности\n",
|
||
"с помощью метода `distplot`, который позволяет одновременно строить как\n",
|
||
"гистограмму, так и непрерывную оценку плотности. В качестве примера\n",
|
||
"рассмотрим бимодальное распределение, состоящее из двух разных\n",
|
||
"стандартных нормальных распределений:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"comp1 = np.random.normal(0, 1, size=200)\n",
|
||
"comp2 = np.random.normal(10, 2, size=200)\n",
|
||
"values = pd.Series(np.concatenate([comp1, comp2]))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.distplot(values, bins=100, color='k')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Диаграммы рассеяния или точечные графики\n",
|
||
"<div id=\"visual:plt-with-pandas:scatter\"></div>\n",
|
||
"\n",
|
||
"Диаграммы рассеяния полезны при изучении связей между двумя одномерными\n",
|
||
"рядами данных. Например, загрузим набор данных из файла\n",
|
||
"[macrodata.csv](src-visual/macrodata.csv.txt) проекта\n",
|
||
"[Statmodels](https://www.statsmodels.org/stable/index.html). Выберем\n",
|
||
"некоторые переменные и вычислим «логарифмические разности»:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"macro = pd.read_csv('src-visual/macrodata.csv')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"data = macro[['cpi', 'm1', 'tbilrate', 'unemp']]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"trans_data = np.log(data).diff().dropna()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"trans_data[-5:]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Теперь воспользуемся функцией `regplot` библиотеки `seaborn`, которая\n",
|
||
"строит графики рассеяния и предлагает график линейной регрессии:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.regplot('m1', 'unemp', data=trans_data)\n",
|
||
"plt.title('Зависимость $\\log$ {} от $\\log$ {}'.format('m1', 'unemp'))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"При анализе данных полезно иметь возможность просматривать все\n",
|
||
"диаграммы рассеяния среди группы переменных, т.е. строить, так\n",
|
||
"называемые, *парные графики* или *матрицу диаграмм рассеяния*. В\n",
|
||
"библиотеке `seaborn` для этого есть удобная функция `pairplot`,\n",
|
||
"которая, в частности, поддерживает размещение гистограмм или оценок\n",
|
||
"плотности каждой переменной по диагонали:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2})"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Категориальные данные\n",
|
||
"<div id=\"visual:plt-with-pandas:facet-grids\"></div>\n",
|
||
"\n",
|
||
"Одним из способов визуализации данных с множеством категориальных\n",
|
||
"переменных является использование сетки фасетов (*facet grid*). В\n",
|
||
"библиотеке `seaborn` есть удобная функция `catplot`, которая\n",
|
||
"упрощает создание сетки фасетов:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.catplot(x='day', y='tip_pct', hue='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Вместо отображения разными цветами столбцов диаграмм в фасете мы\n",
|
||
"также можем расширить сетку фасетов, добавив одну строку по времени:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.catplot(x='day', y='tip_pct', row='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Функция `catplot` поддерживает другие типы графиков, которые могут быть\n",
|
||
"полезны. Например, блочные графики, которые показывают медиану,\n",
|
||
"квартили и выбросы:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false,
|
||
"jupyter": {
|
||
"outputs_hidden": false
|
||
}
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sns.catplot(x='tip_pct', y='day', kind='box', data=tips[tips.tip_pct < 0.5])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Можно создавать свои собственные сетки фасетов,\n",
|
||
"используя более общий класс `seaborn.FacetGrid` (см.\n",
|
||
"[документацию seaborn](https://seaborn.pydata.org/)).\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"visual\" -->\n",
|
||
"<!-- doconce-section-nickname: \"plt-with-pandas\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"visual\" -->\n",
|
||
"<!-- End: -->"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.8.2"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
}
|