将散点图中的标记正确调整为 Matplotlib 中的半径 R

Correct Sizing of Markers In Scatter Plot to a Radius R in Matplotlib

我有一个限制为 -1 到 1 的绘图。 我知道散点图不是以大小为半径绘制的,而是以大小为点绘制的。

我需要根据每个点的大小正确缩放我的图,我将其作为半径。 修改以下代码是否可行?

fig, ax = plt.subplots(1)
ax.set_title("Post Synaptic Neurons")
sizes = [x.size * 100 for x in post_synaptic_neurons]
offsets = [(x.origin[0],x.origin[1]) for x in post_synaptic_neurons]
print(sizes)
ax.scatter([x.origin[0] for x in post_synaptic_neurons], [x.origin[1] for x in post_synaptic_neurons], 
  cmap=plt.cm.hsv, s=sizes, alpha=0.5)
ax.set_xlim([-1,1]) 
ax.set_ylim([-1,1])
ax.set_aspect(1)
plt.tight_layout

如果没有,有人可以向我解释为什么 matplotlib 没有在绘图比例尺上绘制具有特定半径的圆的函数吗? 我没想到这会成为问题,但我的困难背后一定有充分的理由。

据我所知,没有高级方法可以做到这一点,但您可以使用 EllipseCollection 使其工作。由于您的数据不可用,我编造了一些并编写了这段代码:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import EllipseCollection

x, y = 1500 * np.random.rand(2, 100)
size = 50 + 10 * np.random.randn(100)
color = np.random.rand(100)
cmap = plt.cm.hsv

fig, ax = plt.subplots(1, 2, figsize=(16, 6),
                       sharex=True, sharey=True)
ax[0].scatter(x, y, s=size, c=color, cmap=cmap)

offsets = list(zip(x, y))
ax[1].add_collection(EllipseCollection(widths=size, heights=size, angles=0, units='xy',
                                       facecolors=plt.cm.hsv(color),
                                       offsets=offsets, transOffset=ax[1].transData))
ax[1].axis('equal') # set aspect ratio to equal
ax[1].axis([-400, 1800, -200, 1600])

结果如你所愿;左边是简单的散点图,右边是比例图:

如果您缩放绘图,比如将轴限制更改为 ax[1].axis([200, 1000, 300, 900]),则右侧绘图上的圆圈会根据需要缩放:

您可以在 matplotlib docs 中找到更多使用集合的示例。

是的,有一种方法可以在绘图比例尺上绘制具有特定半径的散点图。方法是仔细定义图形大小并以点数指定半径,因为 plt.scatter 的文档说参数 s 是“以点为单位的标记大小**2”。

这是一个在 [0.5, 0.5] 位置绘制半径为 0.1 的圆的示例

import matplotlib.pyplot as plt
plt.figure(figsize=[5, 5])
ax = plt.axes([0.1, 0.1, 0.8, 0.8], xlim=(0, 1), ylim=(0, 1))
points_whole_ax = 5 * 0.8 * 72    # 1 point = dpi / 72 pixels
radius = 0.1
points_radius = 2 * radius / 1.0 * points_whole_ax
ax.scatter(0.5, 0.5, s=points_radius**2, color='r')
plt.grid()
plt.show()

这里的关键是无论dpi如何,matplotlib中点的标准尺寸是每英寸72点(ppi)。 points_radius 公式中的因数 2 是因为面积是 shere 外面的盒子的面积,即 area = (2 * radius)**2。输出图如下图