5.2. Scatter - график разброса (точки)

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

Цвет точек

Цвет линии можно указать с помощью параметра c. Само значение цвета может быть из самых разных цветовых моделей.

Точки одного цвета:

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(1000)    #  x - координаты точек
y = np.random.rand(1000)    #  y - координаты точек

fig, ax = plt.subplots()

ax.scatter(x, y,
           c = 'deeppink')    #  цвет точек

ax.set_facecolor('black')     #  цвет области Axes
ax.set_title('Один цвет')     #  заголовок для Axes

fig.set_figwidth(8)     #  ширина и
fig.set_figheight(8)    #  высота "Figure"

plt.show()

Matplotlib scatter: цвет области и точек

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

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(1000)
y1 = np.random.gamma(1, size = 1000)
y2 = np.random.gamma(2, size = 1000)
y3 = np.random.gamma(4, size = 1000)
y4 = np.random.gamma(8, size = 1000)

fig, ax = plt.subplots()

# ключ цвета из {'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}:
ax.scatter(x, y1,
           c = 'r')
# RGB:
ax.scatter(x + 1, y2,
           c = [[0.1, 0.63, 0.55]])
# hex RGB:
ax.scatter(x + 2, y3,
           c = '#ad09a3')
# уровень серого в интервале [0, 1]:
ax.scatter(x + 3, y4,
           c = ['0.9'])


ax.set_facecolor('black')
ax.set_title('Один цвет')

fig.set_figwidth(8)    #  ширина и
fig.set_figheight(8)    #  высота "Figure"

plt.show()

Matplotlib scatter: цвет области и точек из разных наборов данных

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

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(5000)
y1 = np.random.gamma(1, size = 5000)
y2 = np.random.gamma(2, size = 5000)
y3 = np.random.gamma(4, size = 5000)
y4 = np.random.gamma(8, size = 5000)

fig, ax = plt.subplots()

# ключ цвета из {'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}:
ax.scatter(x, y1,
           c = 'r',
           s = 1)
# RGB:
ax.scatter(x + 1, y2,
           c = [[0.1, 0.63, 0.55]],
           s = 1)
# hex RGB:
ax.scatter(x + 2, y3,
           c = '#ad09a3',
           s = 1)
# уровень серого в интервале [0, 1]:
ax.scatter(x + 3, y4,
           c = ['0.9'],
           s = 1)


ax.set_facecolor('black')
ax.set_title('Один цвет')

#  Увеличим размер графика:
fig.set_figwidth(14)
fig.set_figheight(14)

plt.show()

Matplotlib scatter: цвет области и точек, размер точек и графика

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

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

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(5000)
y1 = np.random.gamma(1, size = 5000)
y2 = np.random.gamma(2, size = 5000)
y3 = np.random.gamma(4, size = 5000)
y4 = np.random.gamma(8, size = 5000)

fig, ax = plt.subplots()

#  RGBA:
ax.scatter(x, y1,
           c = [[1, 0, 0, 0.05]])
#  RGBA:
ax.scatter(x + 1, y2,
           c = [[0.1, 0.63, 0.55, 0.05]])
#  hex RGBA:
ax.scatter(x + 2, y3,
           c = '#ad09a305')
#  RGBA:
ax.scatter(x + 3, y4,
           c = [[0.5, 0, 0.5, 0.05]])


ax.set_title('Прозрачные точки')

fig.set_figwidth(8)    #  ширина и
fig.set_figheight(8)    #  высота "Figure"

plt.show()

Matplotlib scatter: прозрачность точек

RGB и RGBA цвет, который задается с помощью последовательности чисел, а так же уровень серого цвета, задаваемый одним числом нужно указывать в виде двумерной (RGB и RGBA) или одномерной последовательности (например c = ['0.9']). Дело в том, что мы можем задать цвет каждой точки с помощью одномерной последовательности, каждый элемент которой соотносится с точкой из x, y и задает ее цвет:

import numpy as np
import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [1, 2, 3, 4]

fig, axes = plt.subplots(2, 2)


axes[0][0].scatter(x, y,
                   c = ['r', 'g', 'b', 'w'],
                   s = 1000)
axes[0][0].set_facecolor('black')
axes[0][0].set_title('Цвет каждой точки по строке-ключу')

axes[0][1].scatter(x, y,
                   c = [0.9, 0.8, 0.7, 0.6],
                   s = 1000)
axes[0][1].set_facecolor('black')
axes[0][1].set_title('Цвет каждой точки из встроенной палитры')

rgb = [[1, 0, 0], [0, 1, 0],
       [0, 0, 1], [0.5, 0.5, 0.5]]

axes[1][0].scatter(x, y,
                   c = rgb,
                   s = 1000)
axes[1][0].set_facecolor('black')
axes[1][0].set_title('RGB цвет каждой точки')

rgba = [[1, 0, 0, 0.1], [0, 1, 0, 0.1],
       [0, 0, 1, 0.2], [0.5, 0.5, 0.5, 0.3]]

axes[1][1].scatter(x, y,
                   c = rgba,
                   s = 1000)
axes[1][1].set_facecolor('black')
axes[1][1].set_title('RGBA цвет каждой точки')


fig.set_figwidth(12)    #  ширина и
fig.set_figheight(12)    #  высота "Figure"

plt.show()

Matplotlib scatter: различные способы задать цвет точек

Благодаря NumPy мы можем очень легко задать цвет каждой точки или закрасить их по определенному правилу:

# Точки и цвет
import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(500)
y = np.random.rand(500)

fig, axes = plt.subplots(4, 1)

colors = np.random.rand(500)
axes[0].scatter(x, y, c = colors)
axes[0].set_facecolor('black')
axes[0].set_title('Цвет каждой точки из палитры по умолчанию')
axes[0].set_xticks([])

rgb = np.random.rand(500, 3)
axes[1].scatter(x, y, c = rgb)
axes[1].set_facecolor('black')
axes[1].set_title('RGB цвет каждой точки')
axes[1].set_xticks([])

rgba = np.random.rand(500, 4)
axes[2].scatter(x, y, c = rgba)
axes[2].set_facecolor('black')
axes[2].set_title('RGBA цвет каждой точки')
axes[2].set_xticks([])

#  Создаем массив цветов по определенному правилу
#  с помощью логических операций и индексации
#  массивов массивами булевых значений:
col = np.empty_like(y)
below_points = (y < 0.5)    #  скобки нужны для читабельности
upper_point = (y >= 0.5)    #  и понятности
col[below_points] = 0
col[upper_point] = 1

axes[3].scatter(x, y, c = col)
axes[3].set_facecolor('black')
axes[3].set_title('Два цвета для точек выше и ниже 0.5')
axes[3].set_xticks([])
axes[3].set_yticks([0.0, 0.5, 1.0])



fig.set_figwidth(12)     #  ширина и
fig.set_figheight(12)    #  высота "Figure"

plt.show()

Matplotlib scatter: цвет каждой отдельной точки

Точки можно отображать разными маркерами. Установить вид маркера можно, указав соответствующую строку в параметре marker. Толщина линии края маркера задается параметром linewidths, а цвет линии параметром edgecolors. Параметр alpha так же позволяет задавать прозрачность точек:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(50)
y1 = np.random.rand(50)
y2 = np.random.rand(50)

fig, axes = plt.subplots(2, 2)


axes[0][0].scatter(x, y1,
                   marker = 's',
                   c = 'fuchsia')
axes[0][0].set_title('marker, c')

colors_1 = np.random.rand(50)
axes[0][1].scatter(x, y1,
                   marker = '*',
                   c = colors_1,
                   s = 700)
axes[0][1].set_title('marker, c, s')

size = 1000*np.random.rand(50)
axes[1][0].scatter(x, y2,
                   marker = 'o',
                   c = 'lightcoral',
                   s = size,
                   linewidths = 2,
                   edgecolors = 'darkred')
axes[1][0].set_title('marker, linewidths, edgecolors, c, s')

size = 1000*np.random.rand(50)
colors_2 = np.random.rand(50)
axes[1][1].scatter(x, y2,
                   marker = 'o',
                   c = colors_2,
                   s = size,
                   edgecolors = 'black',
                   alpha = 0.6)
axes[1][1].set_title('marker, linewidths, edgecolors, alpha, c, s')

fig.set_figwidth(12)    #  ширина и
fig.set_figheight(12)    #  высота "Figure"

plt.show()

Matplotlib scatter marker: внешний вид, цвет области и края, прозрачность