Рубрики
Без рубрики

Разбросно-разброс Matplotlib – простое иллюстрированное руководство

Все, что вам нужно знать, чтобы начать работу с функцией разброса разброса Matplotlib [+ бонусное видео]

Автор оригинала: Adam Murphy.

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

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

Пример сюжета минимального разброса

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

import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4, 5]
y = [1, 2, 4, 8, 16, 32]

plt.plot(x, y, 'o')
plt.show()

Вы выполняете следующие шаги:

  • Импортируйте модуль MATPLOTLIB.
  • Создайте данные для (х, у) точки.
  • Сюжет данные, используя PLT.PLOT () функция. Первый аргумент является намерением для х ценности. Второй аргумент является утечником для y ценности. Третий аргумент – это стиль точки разброса.

Вот как этот результат выглядит как:

Тем не менее, вы не можете не понравиться стиль этого графика разброса. Давайте погрузимся в более продвинутый пример рядом!

Пример рассеивания Matplotlib

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

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

  • Примечание : Этот набор данных поставляется встроенный как часть морской библиотека.

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

import matplotlib.pyplot as plt
import seaborn as sns

# Optional step
# Seaborn's default settings look much nicer than matplotlib
sns.set()

tips_df = sns.load_dataset('tips')

total_bill = tips_df.total_bill.to_numpy()
tip = tips_df.tip.to_numpy()

Переменная Tips_df это панда Dataframe Отказ Не волнуйтесь, если вы не понимаете, что это еще. Переменные total_bill и наконечник оба Numpy массивы Отказ

Давайте сделаем разброс сюжета total_bill против совет. Очень легко сделать в Matplotlib – используйте PLT.SCatter () функция. Во-первых, мы передаем переменную оси X, а затем ось Y. Мы называем бывшего Независимая переменная и последний зависимая переменная Отказ График разброса показывает, что происходит с зависимой переменной ( y ), когда мы изменяем независимую переменную ( x ).

plt.scatter(total_bill, tip)
plt.show()

Отлично! Похоже, есть положительная корреляция между a . total_bill и кончик . Это означает, что в качестве законопроекта увеличивается, так и совет. Таким образом, мы должны попытаться получить наших клиентов, чтобы потратить как можно больше.

Разбросно разброс Matplotlib с этикетками

Этикетки – это текст на осях. Они рассказывают нам больше о сюжете и важно ли вы включать их на каждый заговор.

Давайте добавим некоторые оси этикетки и заголовок, чтобы проще понять наш разброс.

plt.scatter(total_bill, tip)
plt.title('Total Bill vs Tip')
plt.xlabel('Total Bill ($)')
plt.ylabel('Tip ($)')
plt.show()

Намного лучше. Сохранить место, мы не будем включать лейбл или код заголовка, но убедитесь, что вы делаете.

Это выглядит хорошо, но маркеры довольно велики. Трудно увидеть отношения в стоимостью 10-30 долларов США.

Мы можем исправить это, изменив размер маркера.

Размер маркера Matplotlib

S Ключевое слово аргумент контролирует Размер маркеров в PLT.SCatter () Отказ Он принимает скаляр или массив.

Матплотлиб разброс маркер размер – скаляр

В PLT.SCatter () Размер маркера по умолчанию – S = 72 Отказ

Документы определять S в качестве:

Размер маркера в точках ** 2.

Это означает, что если мы хотим маркера иметь 5, мы должны написать S = 5 ** 2 Отказ

Другие функции MatPlotlib не определяют размер маркера таким образом. Для большинства из них, если вы хотите маркеры с областью 5, вы пишете S = 5 Отказ Мы не уверены, почему PLT.SCatter () Определяет это по-другому.

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

Чтобы установить лучший размер маркера для разброса, нарисуйте его несколько раз с другим S ценности.

# Small s
plt.scatter(total_bill, tip, s=1)
plt.show()

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

# Big s
plt.scatter(total_bill, tip, s=100)
plt.show()

В качестве альтернативы, большое количество делает маркеры больше. Это слишком велико для нашего сюжета и скрывает много данных.

Мы думаем, что S = 20 ударяет хороший баланс для этого конкретного сюжета.

# Just right
plt.scatter(total_bill, tip, s=20)
plt.show()

Есть еще несколько перекрытий между точками, но легче обнаружить. И в отличие от S = 1 , вам не нужно напрягаться, чтобы увидеть разные маркеры.

Размер маркера Matplotlib

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

Вы также записали размер каждой таблицы, который вы ждали. Это хранится в Numpy Array size_of_table. . Он содержит целые числа в диапазоне 1-6, представляющий количество людей, которых вы служили.

# Select column 'size' and turn into a numpy array
size_of_table = tips_df['size'].to_numpy()

# Increase marker size to make plot easier to read
size_of_table_scaled = [3*s**2 for s in size_of_table]

plt.scatter(total_bill, tip, s=size_of_table_scaled)
plt.show()

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

Почему мы масштабировали size_of_table ценности, прежде чем передавать его на S ? Потому что изменение размера не видно, если мы установим S = 1 , …, S = 6 как показано ниже.

Итак, мы впервые побратим каждое значение и умножьте его на 3, чтобы сделать разницу размером более выраженной.

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

Matplotlib рассеяна легенда

Чтобы добавить легенду, мы используем plt.legend () функция. Это легко в использовании с линейными участками. Если мы нарисуем несколько строк на одном графике, мы отмечаем их индивидуально, используя этикетка ключевое слово. Затем, когда мы называем plt.legend () Matplotlib рисует легенду с записью для каждой строки.

Но у нас есть проблема. У нас есть только один набор данных здесь. Мы не можем отметить точки индивидуально, используя этикетка ключевое слово.

Как мы решаем эту проблему?

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

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

Элементы в этом графике разброса являются разными размерами. У нас есть 6 точек разных размеров для представления 6 разных таблиц различных размеров. Так что мы хотим Legend_Elements () Разделить наш сюжет на 6 разделов, которые мы можем метить на нашей легенде.

Давайте выясним, как Legend_Elements () работает. Во-первых, что происходит, когда мы называем это без каких-либо аргументов?

# legend_elements() is a method so we must name our scatter plot
scatter = plt.scatter(total_bill, tip, s=size_of_table_scaled)

legend = scatter.legend_elements()

print(legend)
# ([], [])

Призыв Legend_Elements () Без каких-либо параметров возвращает кортеж длиной 2. Он содержит два пустых списка.

Документы Расскажите нам Legend_Elements () Возвращает кортеж (ручки, этикетки) . Ручки являются частями сюжета, которые вы хотите метить. Ярлыки – это имена, которые появятся в легенде. Для нашего сюжета ручки – это маркеры разных размеров, и этикетки – это цифры 1-6. plt.legend () Функция принимает 2 аргумента: ручки и метки.

plt.legend () Функция принимает два аргумента: PLT.LEGEND (ручки, этикетки) Отказ Как scatter.legend_Elements () Является ли кортеж длиной 2, у нас есть два варианта. Мы можем либо использовать Asterisk * Оператор распаковать его или мы можем распаковать его сами.

# Method 1 - unpack tuple using *
legend = scatter.legend_elements()
plt.legend(*legend)

# Method 2 - unpack tuple into 2 variables
handles, labels = scatter.legend_elements()
plt.legend(handles, labels)

Оба производят один и тот же результат. Документы MATPLOTLIB используют метод 1. Тем не менее, метод 2 дает нам больше гибкости. Если нам не нравятся этикетки Matplotlib, мы можем переписать их самих (как мы увидим в на мгновение).

В настоящее время Ручки и этикетки пустые списки. Давайте изменим это, передавая некоторые аргументы на Legend_Elements () Отказ

Есть 4 Дополнительные аргументы Но давайте сосредоточимся на самом важном: опора Отказ

ОпораНедвижимость из графика разброса вы хотите выделить в своей легенде. По умолчанию «Цвета» Другой вариант – Размеры ' Отказ

Мы рассмотрим различные цветные рассеянные участки в следующем разделе. Как наш участок содержит 6 маркеров разных размеров, мы устанавливаем Prop = 'Размеры' Отказ

scatter = plt.scatter(total_bill, tip, s=size_of_table_scaled)

handles, labels = scatter.legend_elements(prop='sizes')

Теперь давайте посмотрим на содержание обрабатывать и этикетки Отказ

>>> type(handles)
list
>>> len(handles)
6

>>> handles
[,
,
,
,
,
]

Ручки – это список длины 6. Каждый элемент в списке – это matplotlib.lines. Line2d объект. Вам не нужно точно понимать, что это такое. Просто знайте, что если вы пройдете эти объекты в plt.legend () , Matplotlib делает подходящие «Картина» Отказ Для цветных линий это короткая линия этого цвета. В этом случае это единственная точка, и каждая из 6 очков будет другим размером.

Можно создать пользовательские ручки Но это не имеет возможности этой статьи. Теперь давайте посмотрим на этикетки Отказ

>>> type(labels)
list
>>> len(labels)
6

>>> labels
['$\\mathdefault{3}$',
'$\\mathdefault{12}$',
'$\\mathdefault{27}$',
'$\\mathdefault{48}$',
'$\\mathdefault{75}$',
'$\\mathdefault{108}$']

Опять же, у нас есть список длин 6. Каждый элемент является строкой. Каждая строка написана с помощью латексной записи '$ ... $' Отказ Таким образом, этикетки – это цифры 3, 12, 27, 48, 75 и 108.

Почему эти цифры? Потому что они являются уникальными значениями в списке size_of_table_scaled. . Этот список определяет размер маркера.

>>> np.unique(size_of_table_scaled)
array([  3,  12,  27,  48,  75, 108])

Мы использовали эти цифры, потому что использование 1-6 недостаточно разницы размера для замечания людей.

Однако для нашей легенды мы хотим использовать номера 1-6, как это фактический размер таблицы. Так что давайте перезаписать этикетки Отказ

labels = ['1', '2', '3', '4', '5', '6']

Обратите внимание, что каждый элемент должен быть строкой.

Теперь у нас есть все, что нам нужно, чтобы создать легенду. Давайте поставим это вместе.

# Increase marker size to make plot easier to read
size_of_table_scaled = [3*s**2 for s in size_of_table]

# Scatter plot with marker sizes proportional to table size
scatter = plt.scatter(total_bill, tip, s=size_of_table_scaled)

# Generate handles and labels using legend_elements method
handles, labels = scatter.legend_elements(prop='sizes')

# Overwrite labels with the numbers 1-6 as strings
labels = ['1', '2', '3', '4', '5', '6']

# Add a title to legend with title keyword
plt.legend(handles, labels, title='Table Size')
plt.show()

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

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

MATPLOTLIB разброс

Цвет – невероятно важная часть построения. Это может быть целая статья само по себе. Проверьте морской Документы Для большого обзора.

Цвет может сделать или сломать свой участок. Некоторые цветные схемы делают его смехостями легко понять данные. Другие делают это невозможным.

Однако одна из причин изменения цвета чисто для эстетики.

Мы выбираем цвет точек в PLT.SCatter () С ключевым словом C или цвет .

Вы можете установить Любой цвет, который вы хотите Используя кортеж RGB или RGBA (красный, зеленый, синий, альфа). Каждый элемент этих кортежей – это поплавок в [0.0, 1.0] . Вы также можете передавать шестнадцатеричную строку RGB или RGBA, как '# 1F1F1F' Отказ Однако большую часть времени вы будете использовать один из 50+ встроенных названные цвета Отказ Наиболее распространенными являются:

  • 'b' или 'синий'
  • 'R' или 'красный'
  • 'g' или 'зеленый'
  • «К» или 'чернить'
  • 'w' или 'белый'

Вот сюжет total_bill против Совет используя разные цвета

Для каждого сюжета позвоните PLT.SCatter () с total_bill и совет и набор цвет (или C ) на ваш выбор

# Blue (the default value)
plt.scatter(total_bill, tip, color='b')

# Red
plt.scatter(total_bill, tip, color='r')

# Green
plt.scatter(total_bill, tip, c='g')

# Black
plt.scatter(total_bill, tip, c='k')

Примечание : Мы положили участки на одну цифру, чтобы сохранить место. Мы охватим, как это сделать в другой статье (Подсказка: используйте PLT.Subplots () )

MATPLOTLIB разбросает разные цвета

Наш ресторан имеет зону курения. Мы хотим увидеть, если группа сидит в зоне курения, влияет на сумму, которую они советят.

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

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

Мы разделили наши данные в четырехменных массивов:

  • X-AXIS – NON_SMOKING_TOTAL_BILL, Smoking_total_bill
  • y-axis – non_smoking_tip, opering_tip

Если вы рисуете несколько графиков разбросов сразу, MATPLOTLIB цвета по-разному. Это облегчает распознавание различных наборов данных.

plt.scatter(non_smoking_total_bill, non_smoking_tip)
plt.scatter(smoking_total_bill, smoking_tip)
plt.show()

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

Как у нас есть 2 PLT.SCatter () Звонки, мы можем обозначить каждого, а затем звонить plt.legend () Отказ

# Add label names to each scatter plot
plt.scatter(non_smoking_total_bill, non_smoking_tip, label='Non-smoking')
plt.scatter(smoking_total_bill, smoking_tip, label='Smoking')

# Put legend in upper left corner of the plot
plt.legend(loc='upper left')
plt.show()

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

Этот метод работает нормально, если у нас есть отдельные данные. Но большую часть времени мы не разделяем, это может быть утомительно.

К счастью, как с Размер мы можем пройти C массив/последовательность.

Скажем, у нас есть список Курильщик Содержит 1, если таблица копчена и 0, если они этого не сделали.

plt.scatter(total_bill, tip, c=smoker)
plt.show()

Примечание : Если мы пройдем массив/последовательность, мы должны ключевое слово C вместо цвет Отказ Python поднимает ValueError. Если вы используете последнее.

ValueError: 'color' kwarg must be an mpl color spec or sequence of color specs.
For a sequence of values to be color-mapped, use the 'c' argument instead.

Отлично, теперь у нас есть участок с двумя разными цветами в 2 строки кода. Но цвета трудно увидеть.

Matplotlib рассеивает соршук

Сольормап – это диапазон цветов matplotlib использует, чтобы затенить ваши участки. Мы устанавливаем сормер с CMAP аргумент Все возможные Colormaps перечислены здесь Отказ

Мы выберем «BWR» который стоит за сине-белыми красным. Для двух наборов данных он выбирает просто синий и красный.

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

plt.scatter(total_bill, tip, c=smoker, cmap='bwr')
plt.show()

Намного лучше. Теперь давайте добавим легенду.

Как у нас есть один PLT.SCatter () Позвоните, мы должны использовать Scatter.legend_Elements () Как мы делали ранее. На этот раз мы настроим Prop = «цвета» Отказ Но поскольку это настройка по умолчанию, мы называем Legend_Elements () без каких-либо аргументов.

# legend_elements() is a method so we must name our scatter plot
scatter = plt.scatter(total_bill, tip, c=smoker_num, cmap='bwr')

# No arguments necessary, default is prop='colors'
handles, labels = scatter.legend_elements()

# Print out labels to see which appears first
print(labels)
# ['$\\mathdefault{0}$', '$\\mathdefault{1}$']

Мы распадаем нашу легенду в обрабатывать и этикетки как раньше. Затем мы печатаем этикетки, чтобы увидеть заказ matplotlib Он использует восходящий упорядочение. Так 0. (некурящие) сначала.

Теперь мы перезаписываем этикетки с описательными строками и пройти все до plt.legend () Отказ

# Re-name labels to something easier to understand
labels = ['Non-Smokers', 'Smokers']

plt.legend(handles, labels)
plt.show()

Это большой разброс. Легко различать цвета и легенды говорят нам, что они имеют в виду. Как курение нездорово, также приятно, что это представлено красным, как он предлагает «Опасность» Отказ

Что если мы хотели поменять цвета?

Сделайте то же самое, что и выше, но сделайте Курильщик Список 0 для курильщиков и 1 для некурящих.

smokers_swapped = [1 - x for x in smokers]

Наконец, как 0 приходит на первом месте, мы перезаписываем этикетки в обратном порядке до раньше.

labels = ['Smokers', 'Non-Smokers']

MATPLOTLIB разбросных типов маркеров

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

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

В нашем PLT.SCatter () Позвоните, используйте Маркер Аргумент ключевых слов для установки типа маркера. Обычно форма струны отражает форму маркера. Или строка – это одна буква, соответствующая первой букве формы.

Вот самые распространенные примеры:

  • 'o' – Круг (по умолчанию)
  • 'V' – треугольник вниз
  • '^' – треугольник вверх
  • 's' – квадрат
  • '+' – плюс
  • 'D' – алмаз
  • 'D' – тонкий бриллиант
  • '$ ... $' – Латекс синтаксис например '$ \ pi $' Делает каждый маркер греческой буквы π.

Давайте посмотрим некоторые примеры

Для каждого сюжета позвоните PLT.SCatter () с total_bill и совет и набор Маркер на ваш выбор

# Circle
plt.scatter(total_bill, tip, marker='o')

# Plus
plt.scatter(total_bill, tip, marker='+')

# Diamond
plt.scatter(total_bill, tip, marker='D')

# Triangle Up
plt.scatter(total_bill, tip, marker='^')

На момент написания вы не можете пройти массив на Маркер Как вы можете с цвет или размер . Есть Откройте выпуск GitHub Запрашивая, чтобы эта функция добавлена. Но на данный момент, чтобы построить две наборы данных с разными маркерами, вам нужно сделать это вручную.

# Square marker
plt.scatter(non_smoking_total_bill, non_smoking_tip, marker='s',
      label='Non-smoking')

# Plus marker
plt.scatter(smoking_total_bill, smoking_tip, marker='+',
            label='Smoking')

plt.legend(loc='upper left')
plt.show()

Помните, что если вы рисуете несколько графиков разброса сразу, MATPLOTLIB цвета по-разному. Это облегчает распознавание различных наборов данных. Так что в изменении маркера мало значения.

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

# Square marker, blue color
plt.scatter(non_smoking_total_bill, non_smoking_tip, marker='s', c='b'
            label='Non-smoking')

# Plus marker, blue color
plt.scatter(smoking_total_bill, smoking_tip, marker='+', c='b'
            label='Smoking')

plt.legend(loc='upper left')
plt.show()

Больше всего согласится, что разные цвета легче различить, чем разные маркеры. Но теперь у вас есть возможность выбирать.

Резюме

Теперь вы знаете 4 самых важных вещей, чтобы сделать отличные рассеянные участки.

Вы можете сделать базовый MATPLOTLIB рассеянные участки. Вы можете изменить размер маркера, чтобы облегчить понять данные. И вы можете изменить размер маркера на основе другой переменной.

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

Чтобы добавить личность на ваши участки, вы можете использовать пользовательский тип маркера.

Наконец, вы можете сделать все это с сопутствующей легендой (что-то, что большинство Pythonistas не знают, как использовать!).

Куда пойти отсюда

Вы хотите заработать больше денег? Вы в тупике 9-5 работа? Вы мечтаете о разрыве свободным и кодирующим полный рабочий день, но не уверен, как начать?

Становление штатным кодером страшно. Там так много кодирования информации, что она подавляющая.

Большинство учебных пособий учат вам Python и сказать вам, чтобы получить работу на полный рабочий день.

Это нормально Но зачем ли вы хотите другую офисную работу?

Не жаждай свободу? Разве вы не хотите путешествовать по миру? Разве вы не хотите проводить больше времени со своими друзьями и семьей?

Вряд ли есть какие-либо учебные пособия, которые учат вам Python и как быть вашим собственным боссом. И их никто не учит вас, как сделать шесть фигур в год.

До настоящего времени.

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

Звучит слишком хорошо, чтобы быть правдой, верно?

Нисколько. Мы хотим показать вам точные шаги, которые мы использовали здесь. Мы хотим дать вам жизнь свободы. Мы хотим, чтобы вы были шестизначным кодером.

Нажмите на ссылку ниже, чтобы посмотреть наше вебинар Pure-Value. Мы покажем вам точные шаги, чтобы взять вас из того, где вы находитесь в полный рабочий день Python Freelancer. Это доказаны, методы NO-BS, которые получают ваши результаты быстро.

https://tinyurl.com/python-freelancer-webinar

Неважно, если вы начинаете питон или Python Pro. Если вы не делаете шесть фигур/год с Python прямо сейчас, вы узнаете что-то из этого вебинара.

Нажмите на ссылку ниже сейчас и узнайте, как стать фрилансером Python.

https://tinyurl.com/python-freelancer-webinar

использованная литература

Expert Writer & Content Creator – наука о науке и машине.

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

Работать со мной, пожалуйста, обратитесь к Upwork
https://tinyurl.com/hire-adam-murphy.

Оригинал: “https://blog.finxter.com/matplotlib-scatter-plot/”