Вопрос-Ответ

pyplot scatter plot marker size

размер маркера точечной диаграммы pyplot

В документе pyplot для точечной диаграммы:

matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None,
vmin=None, vmax=None, alpha=None, linewidths=None,
faceted=True, verts=None, hold=None, **kwargs)

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


s: размер в пунктах^2. Это скаляр или массив той же длины, что x и y.


Что это за единица измеренияpoints^2? Что это значит? s=100Означает10 pixel x 10 pixel?

По сути, я пытаюсь создавать точечные диаграммы с разными размерами маркеров, и я хочу выяснить, что означает это s число.

Переведено автоматически
Ответ 1

Это может быть несколько запутанным способом определения размера, но вы в основном указываете площадь маркера. Это означает, что для удвоения ширины (или высоты) маркера вам нужно увеличить s в 4 раза. [потому что A = WH => (2W)(2H) = 4A]

Однако есть причина, по которой размер маркеров определяется таким образом. Из-за масштабирования площади как квадрата ширины, удвоение ширины на самом деле увеличивает размер более чем в 2 раза (на самом деле это увеличивает его в 4 раза). Чтобы убедиться в этом, рассмотрим следующие два примера и результат, который они выдают.

# doubling the width of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*4**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

дает

введите описание изображения здесь

Обратите внимание, как быстро увеличивается размер. Если вместо этого мы имеем

# doubling the area of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

дает

введите описание изображения здесь

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

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

Редактировать: (В ответ на комментарий от @Emma)

Вероятно, это сбивающая с толку формулировка с моей стороны. Задан вопрос об удвоении ширины круга, поэтому на первом рисунке для каждого круга (при движении слева направо) его ширина вдвое больше предыдущей, поэтому для области это экспоненциальная величина с основанием 4. Аналогично, во втором примере каждый круг имеет площадь, вдвое превышающую последнюю, что дает экспоненциальную величину с основанием 2.

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

Отредактируйте, чтобы визуализировать комментарий @TomaszGandor:

Вот как это выглядит для различных функций размера маркера:

Экспоненциальный, квадратный или линейный размер

x = [0,2,4,6,8,10,12,14,16,18]
s_exp = [20*2**n for n in range(len(x))]
s_square = [20*n**2 for n in range(len(x))]
s_linear = [20*n for n in range(len(x))]
plt.scatter(x,[1]*len(x),s=s_exp, label='$s=2^n$', lw=1)
plt.scatter(x,[0]*len(x),s=s_square, label='$s=n^2$')
plt.scatter(x,[-1]*len(x),s=s_linear, label='$s=n$')
plt.ylim(-1.5,1.5)
plt.legend(loc='center left', bbox_to_anchor=(1.1, 0.5), labelspacing=3)
plt.show()
Ответ 2

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

Размер в пунктах ^ 2

Аргумент s в plt.scatter обозначает markersize**2. Как сказано в документации


s : скалярный или массивоподобный, форма (n, ), необязательно
размер в точках ^2. По умолчанию используется rcParams['lines.markersize'] ** 2.


Это можно понимать буквально. Чтобы получить маркер размером в x точек, вам нужно возвести это число в квадрат и присвоить его аргументу s.

Таким образом, отношение между размером маркера линейной диаграммы и аргументом размера разброса равно квадрату. Следовательно, для создания маркера точечной диаграммы того же размера, что и маркер точечной диаграммы размером 10 точек, вы должны вызвать scatter( .., s=100).

введите описание изображения здесь

import matplotlib.pyplot as plt

fig,ax = plt.subplots()

ax.plot([0],[0], marker="o", markersize=10)
ax.plot([0.07,0.93],[0,0], linewidth=10)
ax.scatter([1],[0], s=100)

ax.plot([0],[1], marker="o", markersize=22)
ax.plot([0.14,0.86],[1,1], linewidth=22)
ax.scatter([1],[1], s=22**2)

plt.show()

Подключение к "области"

Итак, почему в других ответах и даже документации говорится о "площади", когда речь заходит о s параметре?

Конечно, единицы измерения точек ** 2 являются единицами измерения площади.


  • Для частного случая квадратного маркера, marker="s" площадь маркера действительно напрямую равна значению s параметра.

  • Для круга площадь круга равна area = pi/4*s.

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

введите описание изображения здесь

Однако во всех случаях площадь маркера пропорциональна s параметру. Это мотивирует называть его "area", хотя в большинстве случаев это не так на самом деле.

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

введите описание изображения здесь

Что такое точки?

Пока что ответ на вопрос, что означает размер точечного маркера, дается в единицах измерения точек. Точки часто используются в типографике, где шрифты указываются в точках. Также ширина линии часто указывается в точках. Стандартный размер точек в matplotlib составляет 72 точки на дюйм (ppi) - следовательно, 1 точка равна 1/72 дюйма.

Возможно, было бы полезно иметь возможность указывать размеры в пикселях, а не в точках. Если значение dpi на рисунке также равно 72, одна точка равна одному пикселю. Если dpi рисунка отличается (matplotlib по умолчанию равен fig.dpi=100),

1 point == fig.dpi/72. pixels

Следовательно, хотя размер маркера точечной диаграммы в точках будет выглядеть по-разному для разных точек на дюйм, можно создать маркер размером 10 на 10 пикселей ^ 2, который всегда будет иметь одинаковое количество покрытых пикселей:

введите описание изображения здесь
введите описание изображения здесь
введите описание изображения здесь

import matplotlib.pyplot as plt

for dpi in [72,100,144]:

fig,ax = plt.subplots(figsize=(1.5,2), dpi=dpi)
ax.set_title("fig.dpi={}".format(dpi))

ax.set_ylim(-3,3)
ax.set_xlim(-2,2)

ax.scatter([0],[1], s=10**2,
marker="s", linewidth=0, label="100 points^2")
ax.scatter([1],[1], s=(10*72./fig.dpi)**2,
marker="s", linewidth=0, label="100 pixels^2")

ax.legend(loc=8,framealpha=1, fontsize=8)

fig.savefig("fig{}.png".format(dpi), bbox_inches="tight")

plt.show()

Если вас интересует разброс в единицах данных, проверьте этот ответ.

Ответ 3

Это площадь маркера. Я имею в виду, что если у вас есть s1 = 1000 и затем s2 = 4000, соотношение между радиусом каждой окружности равно: r_s2 = 2 * r_s1. Смотрите следующий график:

plt.scatter(2, 1, s=4000, c='r')
plt.scatter(2, 1, s=1000 ,c='b')
plt.scatter(2, 1, s=10, c='g')

введите описание изображения здесь

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

Ответ 4

Вы можете использовать markersize для указания размера окружности в методе plot

import numpy as np
import matplotlib.pyplot as plt

x1 = np.random.randn(20)
x2 = np.random.randn(20)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(x1, 'bo', markersize=20) # blue circle with size 10
plt.plot(x2, 'ro', ms=10,) # ms is just an alias for markersize
plt.show()

Отсюда

введите описание изображения здесь

python matplotlib