在散点图中将标记的大小调整为Matplotlib中的半径R

时间:2015-10-13 05:04:05

标签: python matplotlib scatter-plot

我有一个限制为-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没有在绘图的比例上绘制具有特定半径的圆的功能吗? 我并不认为这是一个问题,但我的困难背后一定有充分的理由。

2 个答案:

答案 0 :(得分:3)

据我所知,没有高级方法可以做到这一点,但你可以使用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])

结果是你所希望的;左侧的简单散点图,右侧的缩放图: enter image description here

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

enter image description here

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

答案 1 :(得分:2)

是的,有一种方法可以在图的比例尺上绘制具有特定半径的散点图。方式是仔细定义图形尺寸并以点数指定半径,因为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来自这样一个事实,即面积是盒子正好位于透明区域之外的面积,即area = (2 * radius)**2。输出图如下所示。

A circle with a radius of 0.1 in code scale, plot with plt.scatter