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

В документе 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()

дает

enter image description here

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

# 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()

дает

enter image description here

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

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

Надеюсь, это поможет!

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

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

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

Ответ 2

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

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

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

s: scalar или array_like, shape (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()

Подключение к "area"

Итак, почему другие ответы и даже документация говорят о "area", когда дело доходит до параметра 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')

enter image description here

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

Ответ 4

Вы можете использовать markersize, чтобы указать размер круга в методе заговора

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()

От здесь

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

Ответ 5

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

import matplotlib.pyplot as plt
input_list = [{'x':100,'y':200,'radius':50, 'color':(0.1,0.2,0.3)}]    
output_list = []   
for point in input_list:
    output_list.append(plt.Circle((point['x'], point['y']), point['radius'], color=point['color'], fill=False))
ax = plt.gca(aspect='equal')
ax.cla()
ax.set_xlim((0, 1000))
ax.set_ylim((0, 1000))
for circle in output_list:    
   ax.add_artist(circle)

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

Это основано на ответе на этот вопрос

Ответ 6

Если размер окружности соответствует квадрату параметра в s=parameter, тогда присвойте квадратный корень каждому добавляемому элементу массиву размера, например: s=[1, 1.414, 1.73, 2.0, 2.24], чтобы при принятии этих значений и возвращает их, их относительное увеличение размера будет квадратным корнем из квадрата прогрессии, который возвращает линейную прогрессию.

Если бы я должен был скомпоновать каждый, когда он выводит на график: output=[1, 2, 3, 4, 5]. Попробуйте интерпретировать список: s=[numpy.sqrt(i) for i in s]