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

  1. Как построить
  2. Как построить график, используя собственную настройку
  3. Как красиво оформить
  4. Что вы можете построить и почему эти сюжеты используются
  5. Сюжет внутри сюжета. Ура!!! Я второстепенный

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

Если вы не можете понять или у вас есть какой-то конкретный вопрос или настройка, поверьте мне, коллективный разум над stackoverflow может превзойти любой учебник.

Если кто-то из новичков хочет почувствовать, как глубокое обучение и искусственный интеллект работают в реальной жизни, вы можете проверить некоторые из очень сложных моделей компьютерного зрения, развернутых в BookThatStudio, в разделе Сегментация изображений, Улучшение, Релевантность поиска, Рейтинг изображений. и т. д. для решения реальных проблем

Импорт библиотек

import matplotlib.pyplot as plt  # this is basically matplotlib as we know it
import numpy as np  # linear algebra
import pandas as pd  # data processing, CSV file I/O (e.g. pd.read_csv)
import seaborn as sns

# seaborn is a wrapper library which uses matplotlib under the hood to make graphs more beautiful
from pylab import rcParams  # to change the parameters globally
from scipy import stats  # to plot normal distribution

Помощники

SEED = 13
np.random.seed(SEED)  # so that you can re create exactly whats in Notebook

rcParams["figure.figsize"] = 7, 4
plt.style.use("seaborn")


def get_cmap(n, name="hsv", return_cmap=True):
    """Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
    RGB color; the keyword argument name must be a standard mpl colormap name.
    Can throw error if number of colors exceeds the limit of cmap"""
    cmap = plt.cm.get_cmap(name, n)
    if return_cmap:
        return cmap
    else:
        return cmap.colors

Примечание. Пожалуйста, внимательно прочитайте пометки и комментарии, так как они рассказывают вам интересные вещи очень проницательно и Please do not get intimidated by the lines of codes because they are all extra things to customize your plots, поскольку для сюжета требуется всего одна строка кода, такая же простая, как plt.plot([1,2,3,4,5]).

Импорт данных

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

df = pd.read_csv("/kaggle/input/pokemon/Pokemon.csv")
df.drop(
    "#", axis=1, inplace=True
)  # there is this '#' column which is nothing but index
df.head()

Важная заметка

Прежде чем мы начнем, есть некоторые вещи, которые вы должны помнить

  1. Не все сюжеты одинаковы. Некоторые подходят для числового, а другие для категориального
  2. Существуют настройки по умолчанию, которые применяются ко всем графикам, и вы можете изменить их.
  3. Подграфики — это графики внутри графиков, которые широко используются и имеют почти те же функции, что и модуль plt.
  4. matplotlib принимает как numpy, так и панды Dataframes и серии

Общая функциональность

Объект matplotlib в основном представляет собой фигуру с определенными размерами, и вы можете иметь в ней одну фигуру, несколько подграфиков или Если вы строите разные графики на одной и той же фигуре, у вас будут перекрывающиеся экземпляры внутри этой фигуры

Для каждого сюжета есть некоторые общие функции, такие как:

  1. Рисунок: fig = plt.figure(figsize=(5,5) дает нам цифру размера (5,5) для текущей ячейки. Новая фигура инициализируется размерами по умолчанию каждый раз, когда объект plt вызывается в новой ячейке. Обычно нам это не нужно, если только мы не хотим изменить размер фигуры.
  2. Название: plt.title('Here goes the Title) рассказывает нам о том, что представляет собой фигура и что она показывает
  3. Метка X: plt.xlabel('Meaning of X axis') говорит нам о том, что представляет собой ось X на нашем рисунке.
  4. Метка Y: plt.ylabel('Meaning of Y Axis') говорит нам о том, что представляет собой ось X на нашем рисунке.
  5. X, Y Ticks: plt.xticks(), plt.yticks() Изменить цвет галочек по осям x, Y, их отступы, поворот и т. д. и т. д.
  6. Легенда: plt.legend(), когда на одном графике более 2 линий, чем легенда определяет, какая цветная линия представляет какое свойство.
  7. Показать/Сохранить: plt.show(), plt.savefig() показывает или сохраняет фигуру
  8. Цвета: Цвета в matplotlib можно использовать с разными значениями, такими как (0,1,0), 'g', 'green и #00ff00 для зеленого цвета.
  9. Многоцветный: если на одном графике есть несколько графиков, таких как столбцы, линии и т. д., matplotlib генерирует цвета самостоятельно, но если вы хотите задать собственные цвета, вы можете использовать colourmap plt.cm или задать собственный список списков RGB значений 1 для каждой сущности.
  10. Размер: Параметр размера почти такой же, когда нам нужно напечатать строку или какой-либо комментарий, а размер может быть строкой как «большой» или некоторым целым числом, например 12.
figure = plt.figure(figsize=(13, 6))

plt.title(
    "TITLE: This Figure (13,6) demonstrate general attributes with color given in hex (#343ff3) and size=15",
    color="#343ff3",
    size=15,
)

plot1 = plt.plot([4, 1, 4, 6, 9], label="First Line Shows Something inside legend")
plot2 = plt.plot([5, 6, 2, 4, 5], label="Second line has different meaning")
plot3 = plt.plot([3, 7, 6, 4, 0], label="Third Line is of different color")

plt.xlabel(
    "This is X-axis with default size and Red Color [1,0,0] and it shows number (count) of values in our figure as x-large alphabets in teal color",
    color=[1, 0, 0],
)

plt.ylabel(
    'Y-Label with large "g" green fonts, and padding of 40 tells us the range of values',
    color="g",
    labelpad=40,
    size="large",
)

plt.xticks([0, 1, 2, 3, 4], ["a", "b", "c", "d", "e"], color="teal", size="x-large")

plt.legend(loc="best")  # you can do a lot more with legend
# plt.grid() # show a grid in background to show major, minor or both lines and whether for x, y or both axis
# with seaborn style grid is true automatically
plt.show()

Подсюжеты

Почти все люди склонны рассматривать это как последнюю часть, и они склонны делать это по-разному, поскольку существует более 1 метода построения сюжетных линий. TBH, это меня сильно смутило, и я выбрал 1 решение для всех подзаговоров с использованием функциональных методов. То, что я собираюсь сделать ниже, будет очень полезно для вас при создании динамических подсюжетов на ходу. Он просто работает как plt.something(), за исключением именования.

  1. Создание: вы можете создать подсюжеты с помощью figure,axes = plt.subplots(nrows=2,ncols=2,figsize(15,7), которые создадут фигуру отца шириной 15 и высотой 7. Внутри этого будет 4 равномерно расположенных подсюжета. axes — это массив numpy, содержащий 4 разные оси. Вы можете получить доступ тогда как axes[i][j].
  2. Flatten: лучший способ использовать объект осей — ravel() из flatten(), чтобы вы могли индексировать, используя только 1 целое число вместо 2.
  3. Доступ: вы можете просто получить доступ к подсюжетам, просто используя axes[i].plot().
  4. Редактирование: почти все методы, которые вы видели выше, доступны и в подсюжетах, таких как ax[i].set_ylabel() или ax[i].set_title(). Вы можете в любое время обратиться к документации, чтобы проверить соответствующие методы.
  5. Слияние: вы можете объединить 2 подграфика либо по столбцам, либо по строкам, разделить Y, X или обе оси или настроить по своему усмотрению, используя различные доступные методы.
  6. Удаление: вы можете удалить конкретный участок, используя figure.delaxes(ax[i]).

Расстояние между участками в основном зависит от соотношения высоты и ширины фигуры. Записная книжка jupyter может отображать максимальную ширину 15, но графики также могут быть интерактивными, чтобы вы могли увеличивать масштаб определенной части (выходящей за рамки этой записной книжки). Вы всегда можете изменить интервал, изменив параметры интервала по умолчанию, которые равны plt.subplots_adjust(left=0.125, bottom=0.1, right=0.9, top=0.9, wspace=0.2, hspace=0.2). wspace и hspace - относительные пространства ширины и высоты для подграфиков по отношению к общей ширине и высоте. Вы также можете использовать plt.tight_layout() для автоматической настройки подграфиков, чтобы никакие 2 подграфика не касались друг друга.

Подсюжеты мы рассмотрим в следующих разделах

Одномерные графики

Эти графики можно рассматривать как анализ только одной переменной. Например, анализ типа 1 с использованием гистограммы, круговой диаграммы и т. д. или анализ HP с использованием линии или гистограммы и т. д. Далее мы разделим их на 2 категории: числовые и категориальные.

Числовые графики

Это графики, показывающие что-то с числовыми данными, находящимися в диапазоне от -бесконечности до +бесконечности.

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

Используется для поиска шаблона среди заданных точек Специально используется в данных временных рядов

Он строит линию между заданными двумерными точками, и если данные одномерные, он берет range(len(data)) в качестве второй оси. Вы можете поставить maker, изменить linestyle, изменить markersize, изменить linewidth и т. д. Сейчас мы рассмотрим несколько разных вещей.

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

stocks = pd.read_csv(
    "/kaggle/input/national-stock-exchange-time-series/infy_stock.csv", index_col="Date"
)
stocks.head()

# Default Figure Size

sample_stock = stocks.iloc[
    :20, :
]  # First 20 months stocks Prices details only to show clearly

plt.plot(sample_stock["High"], label="Highest (No Marker)")  # default attributes
plt.plot(
    sample_stock["Low"], label="Lowest", ls="dotted", color="green", lw=2, marker="*"
)
plt.plot(
    sample_stock["Close"],
    label="Closed (No Line)",
    linestyle="none",
    marker="o",
    color="m",
    markersize=7,
)

plt.xlabel("Month", size="large")
plt.ylabel("Value", size="large")
plt.xticks(rotation=60)
plt.title("Monthly Share Price Details", size="x-large", color="maroon")

plt.legend()
plt.show()

Гистограмма, графики плотности и вероятности

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

Мы рассмотрим гистограмму распределения с использованием подграфиков

# you can do all of the things using plt.hist() too
f, ax = plt.subplots(2, 2, figsize=(14, 10))  # generate 4 subplots
ax = ax.ravel()
f.suptitle("Super Title: Different visualizations of Histogram")

# matplotlib's histogram
n, bins, patches = ax[0].hist(
    df["Attack"],
    bins=20,
    color="#87ceeb",
)  # try changing the bins to have a different shape
ax[0].set_title("Histogram of Attack vs Number of Pokemons")
ax[0].set_xlabel("Attack Values")
ax[0].set_ylabel("No of Pokemons having Attack Attributes")

# seaborn's distplot # you can also use sns.distplot() withoot 'ax' param if not potting within any subplot
ax[1] = sns.distplot(
    df["Attack"],
    kde=True,
    bins=20,
    ax=ax[1],
    color="#87ceeb",
    fit=stats.norm,
    label="KDE Curve",
)
ax[1].set_ylabel("Count of Pokemons")
ax[1].set_title(
    "Seaborn: distplot | Black curve shows KDE curve if data was NORMALLY Distributed"
)
ax[1].legend()

# seaborn's kdeplot
ax[2] = sns.kdeplot(df["Attack"], shade=True, color="#87ceeb", ax=ax[2])
ax[2].set_ylabel("Probabilities")
ax[2].set_xlabel("Distribution of Attack")
ax[2].set_title("Seaborn: kdeplot")

# Probability Plots
stats.probplot(
    df["Attack"], dist=stats.norm, plot=ax[3]
)  # If data was normal, it would be a straight line

plt.subplots_adjust(wspace=0.25, hspace=0.33)  # change the spacing
plt.show()

Эти графики показывают, что если мы выберем случайного покемона, то существует ОГРОМНАЯ вероятность (около 0,9) того, что он будет иметь атрибут атаки от 40 до 150.

График вероятности показывает нам то же самое и показывает распределение. Если бы данные были совершенно нормальными, это была бы прямая линия из синих точек.

Коробка, Скрипка Сюжеты

Скрипичные графики используются для просмотра распределения статистических значений, таких как среднее значение, медиана и т. д. Коробчатая диаграмма используется для просмотра выбросов в соответствии с теоретическими квантилями 15% и 75%.

num_cols = ["Attack", "Defense", "Speed"]  # numerical column names
num_df = df.loc[
    :, num_cols
]  # matplotlib uses lists or numpy array for multiple boxplots at once

# set Figure and axes
f, ax = plt.subplots(3, 2, figsize=(14, 14))
ax = ax.ravel()

# matplotlib box
ax[0].boxplot(
    num_df.values, labels=num_cols, patch_artist=True, showmeans=True, meanline=True
)
ax[0].set_ylabel("Range of Values")
ax[0].set_title("Matplotlib Boxplot | Red Line:Mean, Green Line:Median")

# seaborn box
ax[1] = sns.boxplot(data=df[num_cols], showmeans=True, meanline=True, ax=ax[1])
ax[1].set_ylabel("Range of Values")
ax[1].set_title("Seaborn Boxplot | Red Line:Mean, Black Line:Median")

# matplotlib Violin
ax[2].violinplot(num_df.values, showmeans=True, showmedians=True)
ax[2].set_ylabel("Range of Values")
ax[2].set_xticks(np.arange(1, len(num_cols) + 1))  # set ticks on x-axis
ax[2].set_xticklabels(num_cols)  # give the ticks labels as the column names
ax[2].set_title("Matplotlib Violinplot with Mean and Median")

# seaborn violin
ax[3] = sns.violinplot(data=df[num_cols], ax=ax[3])
ax[3].set_ylabel("Range of Values")
ax[3].set_title("Seaborn Violinplot")

# overlay first and third plots
ax[4].boxplot(
    num_df.values, labels=num_cols, patch_artist=True, showmeans=True, meanline=True
)
ax[4].violinplot(num_df.values, showmeans=True, showmedians=True)
ax[4].set_ylabel("Range of Values")
ax[4].set_title("Overlaid Box and Violin | Just for demonstration")

f.delaxes(ax[-1])
plt.subplots_adjust(hspace=0.25)
plt.show()

Есть действительно выбросы во всех Атаке, Защите и Скорости, в основном в Защите. Графики скрипки полны в области, где плотность значений максимальна. То есть, как и в нашей гистограмме, она показывает, что у большинства покемонов значения атаки находятся в диапазоне от 50 до 100, а защита в том же диапазоне, но имеет более широкий диапазон от почти 30 до 110.

Категориальные сюжеты

Это графики, показывающие что-то внутри данных, которые распределяются по классам, таким как 0 или 1, черный или белый и т. д.

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

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

PANDAS имеет собственную функцию построения графиков. Вы можете построить базу данных или серию, используя df[col_name].plot(kind='whatever kind of plot you like',args='All the valid arguments for that kind of plot in plt.kind())

counted_unique_values = df[
    "Type 1"
].value_counts()  # this returns a dataframe. Please check how it looks
counted_unique_values.plot(
    kind="pie", autopct="%.2f%%", radius=2.2
)  # use the Pandas plotting Function itself
# autopct tells us how to plot the % signs. Here 2 digits are used after decimal (float) and then a % sign
plt.show()

# Please Trye using
# plt.pie(counted_unique_values,autopct='%1.2f%%',radius=2.2) # You'll find the same thing

Гистограммы

cmap = get_cmap(
    18, "Pastel2", return_cmap=False
)  # 18 different colors (list of RGBA tuples) from Pastel2 style

df["Type 1"].value_counts(normalize=True).plot(kind="bar", color=cmap)
plt.ylabel("Proportion of the the total Pokemon Population")
plt.xlabel("Types of Pokemon | Type 1")
plt.show()

Как видите, круговая и гистограмма показывают одно и то же. Покемоны водного типа составляют больше всего 14% от общей популяции, а меньше всего покемонов летающего типа, которые составляют почти 0% (0,5%).

Многомерные графики

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

Для этого может быть 4 типа графиков

  1. Числовое — числовое отношение
  2. Категориальное — категориальное отношение
  3. Категориальный — Числовой
  4. Смешайте эти 3, чтобы иметь как минимум 3 переменные на одном графике.

Графики рассеяния

Показывает взаимосвязь между двумя числовыми атрибутами.

Ниже представлена ​​демонстрация точечных диаграмм от простого к сложному

f, ax = plt.subplots(3, 2, figsize=(15, 19))
ax = ax.ravel()
sample = df.sample(300, random_state=SEED)  # random 300 samples

# first plot. Simple single Plot
ax[0].scatter(x=sample["Attack"], y=sample["Speed"], facecolor="green")
ax[0].set_ylabel("Speed", size="large")
ax[0].set_xlabel("Attack", size="large")
ax[0].set_title(" Default | 2 Attributes", color="green", size="x-large")

# multiple scatter plots in one
ax[1].scatter(
    x=sample["Attack"],
    y=sample["Speed"],
    s=40,
    facecolor=None,
    edgecolor="teal",
    marker="*",
    alpha=0.85,
    label="Attack Vs Speed",
)  #  Teal colored Stars with less opacity and size=40

ax[1].scatter(
    x=sample["Attack"],
    y=sample["HP"],
    facecolor="none",
    edgecolor="black",
    linewidth=2,
    label="Attack Vs HP",
)  # black hollow circles with thick boundry

ax[1].set_xlabel("Attack", size="large")
ax[1].set_ylabel("Speed / HP", size="large")
ax[1].set_title("Two Plots in one | 3 Attributes | ", color="green", size="x-large")
ax[1].legend()

# Three variables in single Plot. Size shows the Legendary of Pokemon
ax[2] = sns.scatterplot(
    x="Attack",
    y="Speed",
    size="Type 1",
    hue="Type 1",
    data=sample,
    ax=ax[2],
    sizes=(10, 200),
)
# change color of dots by using args of plt.scatter()
ax[2].set_xlabel("Attack", size="large")
ax[2].set_ylabel("Speed", size="large")
ax[2].set_title(
    '3 Attributes in Single Plot | Marker "Size" Show Type 1',
    color="green",
    size="x-large",
)

# Three variables in single Plot. Size shows the Type 1 of Pokemon
ax[3] = sns.scatterplot(
    x="Attack", y="Speed", hue="Legendary", data=sample, ax=ax[3], s=100
)
# s is the size of dots
ax[3].set_xlabel("Attack", size="large")
ax[3].set_ylabel("Speed", size="large")
ax[3].set_title(
    '3 Attributes in Single Plot | Marker "Hue" Show Legendary',
    color="green",
    size="x-large",
)


# Three variables in single Plot. Marker shows the Legendary of Pokemon
ax[4] = sns.scatterplot(
    x="Attack", y="Speed", style="Legendary", data=sample, ax=ax[4], facecolor="m", s=85
)
ax[4].set_xlabel("Attack", size="large")
ax[4].set_ylabel("Speed", size="large")
ax[4].set_title(
    '3 Attributes in Single Plot | Marker "Style" Show Legendary',
    color="green",
    size="x-large",
)

f.delaxes(ax[-1])
plt.subplots_adjust(hspace=0.25)

plt.show()

Как читать сюжеты??

Что мы можем видеть из Plot 1 and 2, так это то, что покемоны с высокой атакой, как правило, имеют более высокие значения скорости и атаки, и Hp имеет такое же соотношение.

Plot 4 and 5 говорит нам, что покемоны с категорией Legendary, все имеют высокую скорость и высокую атаку

Примечание. Я намеренно использовал hue=Type 1 и size=Type 1, чтобы одинаковые атрибуты размера имели одинаковый цвет, потому что это могло быть неоднозначно. Вы не должны использовать размер для классов с большим количеством корзин, так как вы не сможете увидеть разницу в размерах своими глазами.

Plot 3 показывает нам, что электрические покемоны имеют высокую скорость, но меньшую мощность, поскольку вы можете видеть самые большие точки в районе скорости 100-140 и атаки 25-125. Steel У покемонов высокая атака, но низкая скорость, что видно по мельчайшим точкам. Normal Покемоны действительно нормальны, так как их статистика находится в середине диаграммы.

f, ax = plt.subplots(1, 2, figsize=(15, 11))
ax = ax.ravel()

# Four variables in single Plot. Size shows the Legendary of Pokemon and Hue  shows  Type 1
ax[0] = sns.scatterplot(
    x="Attack",
    y="Speed",
    size="Type 1",
    hue="Type 1",
    style="Legendary",
    data=sample,
    ax=ax[0],
)
ax[0].set_xlabel("Attack", size="large")
ax[0].set_ylabel("Speed", size="large")
ax[0].set_title(
    '4 Attributes in Single Plot | "Size" Show Type 1 | "Style" Show Legendary',
    color="green",
    size="large",
)


# Five variables in single Plot. Size shows the Legendary of Pokemon, Hue  shows  Type 1 Size Shows Type 2
ax[1] = sns.scatterplot(
    x="Attack",
    y="Speed",
    size="Type 2",
    sizes=(10, 200),
    hue="Type 1",
    style="Legendary",
    data=sample,
    ax=ax[1],
)
ax[1].set_xlabel("Attack", size="large")
ax[1].set_ylabel("Speed", size="large")
ax[1].set_title(
    '5 Attributes in Single Plot | "Hue" Show Type 1 | "Size" shows Type 2 | "Style" Show Legendary',
    color="green",
    size="large",
)

plt.show()

Графики регрессии

Графики регрессии используются для подтверждения связи двух числовых атрибутов (то, что мы видим на диаграммах рассеяния) путем подбора линии регрессии. Регрессия говорит нам о том, что представляет собой образец двух переменных и виден r square {-1,1}, который является не чем иным, как числом, определяющим, как два числовых значения связаны друг с другом.

  1. Если два атрибута имеют r square значение -1, это означает, что существует огромное отношение, и если один атрибут увеличивается, другой уменьшается. ``.
  2. Если значение равно 1, это означает, что существует положительная совершенная связь и две переменные увеличиваются в одинаковой пропорции одновременно. `
  3. 0 баллов означает отсутствие какой-либо закономерности и взаимосвязи. Например, Mileage of a Car и Brightness of a star.
# plt.scatter() and plt.line() arguments can be passed here
scatter_kws = {"edgecolor": "red", "s": 100, "alpha": 0.85, "linewidth": 1}
sns.regplot(
    x="Attack",
    y="Speed",
    data=sample,
    ci=90,
    color="green",
    marker="*",
    scatter_kws=scatter_kws,
)
plt.title(
    "Attack vs Speed Regression Plot with 90% Confidence Interval",
    size="x-large",
    color="blue",
)
plt.show()

Совместный участок

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

Вы можете пройти из разных kind = “scatter” | “reg” | “resid” | “kde” | “hex”

j = sns.jointplot("Attack", "Defense", data=sample, color="green", kind="reg")

plt.subplots_adjust(top=0.9)  # there are 3 subplots so to adjust the title
j.fig.suptitle(
    "Attack vs Defense Joint-Regression Plot with Probability Distributions",
    size="x-large",
    color="maroon",
)
plt.show()

Между осями X и Y есть прямая линия. Это могло бы быть идеальное отношение, если бы та же линия проходила и через начало. В нашем случае Атака и Защита увеличиваются вместе. Люди с высокой атакой, как правило, имеют и высокую защиту.

График подсчета, двумерные диаграммы

Используется для просмотра распределения классов по классам

f, axs = plt.subplots(2, 1, figsize=(10, 10))

axs[0] = pd.crosstab(df["Type 1"], df["Legendary"]).plot(
    kind="bar", width=0.85, ax=axs[0], cmap="Set2", stacked=True
)
axs[0].set_title(
    "Stacked (Count) Bar Plot Using Pandas Plotting (built in plt.bar())",
    color="green",
    size="x-large",
)

axs[1] = sns.countplot(x="Type 1", hue="Legendary", data=df, ax=axs[1], palette="husl")
axs[1].set_title("Count Plot Using Seaborn", color="green", size="x-large")

for ax in axs:  # set tick labels and Y labels for both of the sublots at once
    plt.setp(ax.get_xticklabels(), rotation=45)
    ax.set_ylabel("Count")

plt.subplots_adjust(hspace=0.4)
plt.show()

Никакие Bug, Fighting, Poison типов покемонов не являются легендарными. Несмотря на то, что Flying покемонов меньше, соотношение легендарных и обычных составляет около 1.

Dragon Тип покемонов имеет второе отношение легендарного к нелегендарному.

Большинство чисел легендарных покемонов относятся к категории Psychic, хотя соотношение меньше, чем Dragon и Flying.

Коробка, Скрипка (двухвариантная)

Когда мы хотим увидеть распределение числовых значений и их характеристик в каждом классе, мы используем Box и Violin с классом.

f, ax = plt.subplots(2, 1, figsize=(15, 9))
ax = ax.ravel()

ax[0] = sns.boxplot(
    x="Type 1", y="Attack", data=df, ax=ax[0], dodge=True, meanline=True, showmeans=True
)
ax[0].set_title("Attack Box Plot for Each Type 1")

ax[1] = sns.violinplot(x="Type 1", y="Attack", data=df, ax=ax[1], dodge=True)
ax[1].set_title("Attack Violin Plot for Each Type 1")

plt.subplots_adjust(hspace=0.33)
plt.show()

Из Box Plot мы можем наблюдать, что данные для Fighting, Rock and Flying имеют левое или отрицательное искажение, потому что среднее значение (красная пунктирная линия) меньше медианы (черная сплошная линия).

Из всех выбросов, присутствующих в атаке, только Steel and Normal покемонов имеют выбросы на наименьшем конце, то есть значения меньше, чем (1,5 * Q1). Из-за аномальных выбросов в Fairy среднее значение сместилось в сторону выбросов.

Water and Dragon имеют почти совершенно нормальное распределение, и их можно увидеть как на графиках Box, так и на Violin Plots.

Из всех типов покемонов Dragon тип покемонов имеет самый высокий средний показатель и дальность атаки.

Графики Dist, Hist Plots (для двумерного анализа)

Распределение числовых атрибутов в каждом классе можно легко увидеть с помощью таких графиков.

f, ax = plt.subplots(1, 2, figsize=(15, 5))


ax[0] = sns.distplot(
    df[df["Legendary"] == True]["Attack"],
    kde=True,
    ax=ax[0],
    color="#87ceeb",
    label="Legendary",
)
ax[0] = sns.distplot(
    df[df["Legendary"] == False]["Attack"],
    kde=True,
    ax=ax[0],
    color="#FFB6C1",
    label="Not Legendary",
)
ax[0].set_ylabel("Count of Pokemons")
ax[0].set_title(
    "Seaborn: distplot | Distributon of attack in Legendary and Not Legendary"
)
ax[0].legend()

# seaborn's kdeplot
ax[1] = sns.kdeplot(
    df[df["Legendary"] == True]["Attack"],
    shade=True,
    color="#87ceeb",
    ax=ax[1],
    label="Legendary",
)
ax[1] = sns.kdeplot(
    df[df["Legendary"] == False]["Attack"],
    shade=True,
    color="#FFB6C1",
    ax=ax[1],
    label="Not Legendary",
)
ax[1].set_ylabel("Proportion of the Whole Data")
ax[1].set_xlabel("Attack ")
ax[1].set_title(
    "Seaborn: kdeplot | Distributon of attack in Legendary and Not Legendary"
)

plt.show()

Это показывает, что большинство покемонов (режим или пик), которые являются легендарными, как правило, имеют значения атаки от 90 до 120 и высокий диапазон атаки от 30 до 200, но простые покемоны, как правило, имеют более низкий диапазон атаки от 1 до 150 и у большинства из них Атака 30–70.

Полоса, роевые участки

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

Чтобы лучше понять оба сюжета, мы также будем использовать перекрывающиеся сюжеты для скрипки и ящика, чтобы мы могли лучше понять их

В полосовом графике дрожание может быть от 0 до 1, но это просто случайный набор значений и НЕ является правильным приближением распределения

f, ax = plt.subplots(2, 2, figsize=(15, 11))
ax = ax.ravel()

ax[0] = sns.boxplot(x="Legendary", y="Attack", data=df, ax=ax[0], color="0.8")
ax[0] = sns.stripplot(x="Legendary", y="Attack", data=df, ax=ax[0], jitter=True)
ax[0].set_title("Stip with Box Plot")

ax[1] = sns.violinplot(x="Legendary", y="Attack", data=df, ax=ax[1], color="0.8")
ax[1] = sns.stripplot(x="Legendary", y="Attack", data=df, ax=ax[1], jitter=0.25)
ax[1].set_title("Stip with Violin Plot")

ax[2] = sns.boxplot(x="Legendary", y="Attack", data=df, ax=ax[2], color="0.8")
ax[2] = sns.swarmplot(x="Legendary", y="Attack", data=df, ax=ax[2], size=4)
ax[2].set_title("Swarm with Box Plot")

ax[3] = sns.violinplot(x="Legendary", y="Attack", data=df, ax=ax[3], color="0.8")
ax[3] = sns.swarmplot(x="Legendary", y="Attack", data=df, ax=ax[3], size=4)
ax[3].set_title("Swarm with Violin Plot")

plt.show()

У многих покемонов общего типа есть атака 40–900, и поэтому у нас есть толстая фигура в середине сюжета скрипки. Многие покемоны легендарного типа также имеют дальность атаки 100.

fig = plt.figure(figsize=(15, 6))

plt.title("Swarm Plot with Hue as Type 1")
sns.swarmplot(x="Type 1", y="HP", hue="Legendary", data=df, size=7, palette="Set2")
plt.show()

У Dragon и Psychic покемонов есть много легендарных покемонов, принадлежащих им. Соотношение равно 1 для Flying. Покемонов в нижнем диапазоне ХП почти нет. Все легендарные покемоны, как правило, имеют HP более 70, за исключением нескольких с чуть более 50.

Точечный участок

Ниже приведен пример из Seaborn's Demo о точечном графике:

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

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

tips = sns.load_dataset("tips")
tips.head()

f, ax = plt.subplots(1, 2, figsize=(15, 4.5))

ax[0] = sns.pointplot(
    x="time", y="tip", data=tips, ax=ax[0]
)  # default mean with 95% confidence interval
ax[0].set_title("Tip given vs Time of Day", size="x-large")

ax[1] = sns.pointplot(
    x="day",
    y="tip",
    hue="smoker",
    data=tips,
    estimator=np.median,
    ci=99,
    dodge=True,
    markers=["o", "x"],
    linestyles=["-", "--"],
    palette="husl",
    ax=ax[1],
    seed=SEED,
)
# dodge is to seperate the two so that they do not overlab
ax[1].set_title(
    "Tip vs Time of Day given whether there was a Smoker or not", size="x-large"
)

plt.show()

В среднем за ужином дают больше чаевых, чем за обедом.

Количество чаевых, которые дают курильщики, увеличивается с пятницы по воскресенье, и в воскресенье они дают больше чаевых, чем некурящие по воскресеньям. Чаевые, данные некурящими, увеличиваются с четверга по пятницу, но уменьшаются с пятницы по воскресенье с высокой ошибкой между ними (длина столбца в пятницу также находится на отрицательном конце).

Расширенные графики

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

Парный участок

Парный график показывает отношение каждой переменной к каждой другой переменной в DataFrame только для ЧИСЛОВЫХ данных. Если у вас есть категории, используйте их с LabelEncoding.

label_df = df.drop(
    [
        "Type 1",
        "Type 2",
        "Name",
        "Generation",
    ],
    axis=1,
)
label_df.head()

sns.pairplot(
    label_df.dropna(), kind="scatter", diag_kind="kde", hue="Legendary", palette="husl"
)
# plot reression plot for every numerical attribute with 'kde' plot for diagonals where the class separation is
# according to Legendary

plt.show()
# you should most probabily save the figure if it not feasible to show

Реляционный сюжет

relplot может отображать связь между 2 числовыми атрибутами, разделенными максимум 4 дополнительными категориальными атрибутами.

Он может построить “scatter, line”

Примечание. Количество строк, столбцов и размер диаграммы зависят от количества классов и атрибутов, которые вы хотите отобразить. Он может отображать связь между максимум 2 numerical атрибутами и всего 6 атрибутами.

sns.relplot(
    x="total_bill",
    y="tip",
    row="size",
    col="day",
    hue="time",
    style="smoker",
    kind="scatter",
    data=tips,
    height=3.3,
    aspect=1,
    s=133,
)
# you can put the respective matplotlib args for the respective 'kind'
plt.show()

Чтобы узнать, что означает диаграмма, просто посмотрите на диаграмму 2nd row,2nd column. Этот график говорит, что:

  1. На Fridays значения tip и total_bill увеличиваются одновременно, и большая часть tips и total_bill дается людьми, которые являются smoker и входят в группу size=2. (blue-crosses в правом верхнем углу)
  2. Люди, которые smoker и приходят size из 2 на обед time, не дают столько tip и total_bill (green-crosses)
  3. В пятницу на ужин time очень мало non smoking человек, которые приходят size из 2. (blue-circle)
  4. Нет людей, которые non smoker и приходят на обед time в количестве size из 2 по пятницам.(absence of green-circle)

По четвергам (day=thursday) пары (size=2), как правило, обедают (time='lunch) вместо ужина и платят хорошие чаевые по счетам. (вторая строка, первый столбец: все green)

Независимо от размера и курения, люди хотят обедать вместо ужина по четвергам (первый ряд весь зеленый, без синего)

Все хотят ужинать вместо обеда по субботам и воскресеньям, независимо от размера и привычек курения (все синие, а не зеленые в последних двух столбцах)

Категориальный сюжет

catplot похож на relplot, но с большим акцентом на отображение категориальных атрибутов.

Он может построить “point”, “bar”, “strip”, “swarm”, “box”, “violin”, or “boxen”

Примечание. Он также может относиться к 5 различным атрибутам, но включает только один числовой атрибут.

# pass one of either X or Y in count plot
sns.catplot(
    x="size", row="smoker", col="day", hue="time", kind="count", data=tips, height=3.3
)
plt.show()

Некоторые интерпретации:

  1. Почти никто (кроме очень немногих пар) не хочет ужинать по четвергам, а обедать по субботам и воскресеньям хотят буквально все. (Первый столбец весь синий, последние 2 столбца все зеленые)
  2. По пятницам люди почти не ходят, за исключением некоторых пар и групп из 3 человек (вторая колонка). Некурящие пары, как правило, идут только на ужин, а группа некурящих из 3 человек идет на обед (2-й ряд, вторая колонка).
  3. Некурящие пары ходят обедать по четвергам гораздо чаще, чем курящие пары. (разница между 1-й и 2-й строкой 1-го столбца)
sns.catplot(
    y="tip",
    x="size",
    row="smoker",
    col="day",
    hue="time",
    kind="swarm",
    data=tips,
    height=3.3,
)
plt.show()

Спасибо!!!

За то, что уделили время этому блокноту, и, пожалуйста, предложите какие-либо исправления. Если вы хотите узнать больше об обработке изображений, глубоком обучении, Keras или PyTorch, ознакомьтесь с другими моими блокнотами.