Глава 3 Data Science from Scratch знакомит нас с визуализацией данных с помощью matplotlib. Это широко используется в экосистеме Python, хотя я чувствую, что люди так же, если не больше, рады использовать другие библиотеки, такие как seaborn, Altair и bokeh. (примечание: Seaborn построен поверх matplotlib).

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

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

Базовый график

В этой главе рассматриваются основные базовые диаграммы, включая линейные, столбчатые, гистограммы и точечные диаграммы. На первый взгляд они следуют похожему шаблону. Данные предоставляются в виде list чисел (обычно более одного списка). pyplot импортируется из matplotlib как plt. Модуль plt имеет несколько функций, которые используются для создания графика.

Вот пример линейной диаграммы, отображающей рост ВВП с течением времени:

Вот код:

from matplotlib import pyplot as plt
# the data
years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]
gdp = [300.2, 543.3, 1075.9, 2862.5, 5979.6, 10289.7, 14958.3]
# the plot
plt.plot(years, gdp, color="green", marker='o', linestyle='solid')
plt.title("Nominal GDP")
plt.ylabel("Billions of $")
plt.xlabel("Years")
plt.show()

Вы можете немного обойтись, просто зная это. Кратко ознакомившись с документацией, вы увидите некоторые другие типы диаграмм, например:

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

from matplotlib import pyplot as plt
years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]
gdp = [300.2, 543.3, 1075.9, 2862.5, 5979.6, 10289.7, 14958.3]
plt.stackplot(years, gdp, color="green") # this is the only line we changed
plt.title("Nominal GDP")
plt.ylabel("Billions of $")
plt.xlabel("Years")
plt.show()

Вот как выглядит составная диаграмма с областями предыдущего графика:

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

Вот пример гистограммы, в которой фильмы сравниваются по количеству полученных ими наград Академии:

Вот версия основного графика:

Как и в предыдущем примере, изменение только одной функции с plt.bar на plt.stem дало нам другой график:

#---- Original Bar Chart ----#
movies = ["Annie Hall", "Ben-Hur", "Casablanca", "Gandhi", "West Side Story"]
num_oscars = [5,11,3,8,10]
plt.bar(range(len(movies)), num_oscars)
plt.title("My Favorite Movies")
plt.ylabel("# of Academy Awards")
plt.xticks(range(len(movies)), movies)
plt.show()
# ---- Stem Chart ---- #
movies = ["Annie Hall", "Ben-Hur", "Casablanca", "Gandhi", "West Side Story"]
num_oscars = [5,11,3,8,10]
plt.stem(range(len(movies)), num_oscars) # the only change
plt.title("My Favorite Movies")
plt.ylabel("# of Academy Awards")
plt.xticks(range(len(movies)), movies)
plt.show()

Для этого есть уровни: Иерархия

Я полностью за то, чтобы matplotlib был как можно более простым, но одна вещь, которую приведенные выше примеры замалчивают, — это иерархия объектов matplotlib, которую стоит понять, чтобы понять, как работают различные функции.

Следующий рисунок заимствован из Real Python и хорошо подчеркивает иерархию, присущую каждому сюжету:

Вы заметите уровни: Figure, Axes и Axis. При копании документации matplotlib по осям эти уровни выдвигаются на первый план.

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

Вот код:

# BOOK version
variance = [1,2,4,8,16,32,64,128,256]
bias_squared = [256, 128, 64, 32, 16, 8, 4, 2, 1]
total_error = [x + y for x,y in zip(variance, bias_squared)]
xs = [i for i, _ in enumerate(variance)]
plt.plot(xs, variance, 'g-', label='variance')
plt.plot(xs, bias_squared, 'r-', label='bias^2')
plt.plot(xs, total_error, 'b:', label='total error')
plt.legend(loc=9)
plt.xlabel("model complexity")
plt.xticks([])
plt.title("The Bias-Variance Tradeoff")
plt.show()
# ALTERNATE version
variance = [1,2,4,8,16,32,64,128,256]
bias_squared = [256, 128, 64, 32, 16, 8, 4, 2, 1]
total_error = [x + y for x,y in zip(variance, bias_squared)]
xs = [i for i, _ in enumerate(variance)]
fig, ax = plt.subplots(figsize=(8,5))
ax.plot(xs, variance, 'g-', label='variance')
ax.plot(xs, bias_squared, 'r-', label='bias^2')
ax.plot(xs, total_error, 'b:', label='total error')
ax.legend(loc='upper center')
ax.set_xlabel("model complexity")
ax.set_title("The Bias-Variance Tradeoff: Alt Version")
fig.tight_layout()
fig.show()

Вместо модуля plt мы используем fig и ax, вот их типы данных:

type(fig) # matplotlib.figure.Figure
type(ax)  # matplotlib.axes._subplots.AxesSubplot

Это делает явной иерархию объектов matplotlib, особенно когда мы видим, как мы получаем доступ к функции на уровне axes._subplits.AxesSubplot (документация содержит гораздо больше деталей).

Вот диаграмма:

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

***

Чтобы узнать больше о науке о данных, машинном обучении, R, Python, SQL и многом другом, найдите меня в Twitter.