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)

标记笔大小

< p >史: 大小单位是点^2。与x、y长度相同的标量或数组。

points^2是什么类型的单位?这是什么意思?s=100是指10 pixel x 10 pixel吗?

基本上,我试图用不同的标记大小制作散点图,我想弄清楚s数字的含义。

1451650 次浏览

这种定义大小的方式可能会让人有些困惑,但你基本上是在指定标记的区域。这意味着,要将标记的宽度(或高度)增加一倍,您需要将s增加4倍。[因为A = WH =比;(2 w)(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倍的面积,而不是半径,这样表观大小与面积成线性比例。

编辑来可视化@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()

如果圆圈的大小对应于s=parameter中的参数的平方,则为添加到size数组中的每个元素分配一个平方根,例如:s=[1, 1.414, 1.73, 2.0, 2.24],这样当它获取这些值并返回它们时,它们的相对大小增加将是平方级数的平方根,这将返回一个线性级数。

如果我在输出到绘图时对每一个进行平方:output=[1, 2, 3, 4, 5]。尝试列表解释:s=[numpy.sqrt(i) for i in s]

它是标记的区域。我的意思是,如果你有s1 = 1000s2 = 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

当我看到这篇文章时,我也有同样的怀疑,所以我做了这个例子,然后我用屏幕上的尺子来测量半径。

你可以在plot方法中使用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()

从# EYZ0

enter image description here

为了达到这个目的,我最初也尝试使用“散射”。在浪费了相当多的时间后,我确定了以下解决方案。

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)

enter image description here

这是基于对这个问题的回答

# EYZ1

大小单位是点^2

plt.scatter中的参数s表示markersize**2。如文档所述

s:标量或array_like,形状(n,),可选
大小单位是点^2。默认为rcParams['行。Markersize '] ** 2.

这可以从字面上理解。为了获得x点大的标记,需要对该数字进行平方,并将其赋给s参数。

线形图的标记大小和散点大小参数之间的关系是平方。为了生成与大小为10点的plot标记相同大小的散点标记,您可以将其称为scatter( .., s=100)

enter image description here

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
  • 对于其他标记,甚至可能与标记的面积没有任何明显的关系。

enter image description here

# EYZ1。这就是称之为“区域”的动机,尽管在大多数情况下它并不是真的。

将散射标记的大小指定为与标记面积成比例的某种数量,在目前意义上,因为它是在比较不同斑块时感知到的标记面积,而不是其边长或直径。也就是说,基础数量翻倍时,标记的面积也要翻倍。

# EYZ0

什么是积分?

到目前为止,散点标记的大小是以点为单位给出的。在排版中经常使用点,其中字体用点指定。线宽通常用点来表示。matplotlib中的点的标准大小是72点每英寸(ppi) - 1点因此是1/72英寸。

如果能够以像素而不是点来指定大小,可能会很有用。如果dpi也是72,那么一个点就是一个像素。如果数字dpi不同(matplotlib默认为fig.dpi=100),

1 point == fig.dpi/72. pixels

虽然对于不同的dpi图,散点标记的点大小看起来不同,但可以生成一个10 × 10像素^2的标记,它总是具有相同数量的像素覆盖:

enter image description here enter image description here # EYZ0 < / p >

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

如果您对数据单元中的散点感兴趣,请选中这个答案