Matplotlib:散点图圆的质心

时间:2011-12-13 16:47:20

标签: python matplotlib

我有一个Matplotlib散点图,绘制了3个不同的圆圈,我试图找到每个圆圈的中心点的轴x,y坐标,即bbox中0到1之间的数字。我正在尝试这样做是因为我将图像保存为.png文件,并希望在.png文件的(512,1024)空间中找到相应的x,y点。

我尝试使用以下代码,但我不知道如何解释这些打印的顶点和代码:

ax = fig.gca()
for collection in ax.collections:
    for path in collection._paths:
        for p in path.iter_segments():
            print p

它为三个圆圈打印了10个数组,但这对我没有意义,因为只有三个圆圈,我似乎无法找到任何有助于解释这一点的文档:

(array([0,-0.5]),1)

(array([0.13260155,-0.5,0.25978994,-0.44731685,0.35355339,        -0.35355339]),4)

(数组([0.44731685,-0.25978994,0.5,-0.13260155,0.5,0。]),4)

(array,[0.5,0.13260155,0.44731685,0.25978994,0.35355339,         0.35355339]),4)

(array([0.25978994,0.44731685,0.13260155,0.5,0。,         0.5]),4)

(array([ - 0.13260155,0.5,-0.25978994,0.44731685,-0.35355339,         0.35355339]),4)

(数组([ - 0.44731685,0.25978994,-0.5,0.13260155,-0.5,0。]),4)

(array([ - 0.5,-0.13260155,-0.44731685,-0.25978994,-0.35355339,        -0.35355339]),4)

(array([ - 0.25978994,-0.44731685,-0.13260155,-0.5,0。,        -0.5]),4)

(array([0.,-0.5]),79)

由于

1 个答案:

答案 0 :(得分:3)

我想您可能对ax.transData转换感兴趣。使用transform方法,您可以将“数据”单位中的点转换为显示单位。有关详细信息,请参阅transformation tutorial

下面我有一个示例,其中包含一个填充整个图的轴,因此更容易理解转换。我在散点图中设置了三个点,然后,我将用于绘图的数据用于变换,获得三个点中每个点的对应点(以像素为单位)。

import matplotlib.pyplot as plt

x = [1,2,4]
y = [1,3,2]

fig1 = plt.figure(figsize=(5,5),dpi=100)
ax = fig1.add_axes([0,0,1,1])

ax.scatter(x,y)

ax.set_xlim(0,5)
ax.set_ylim(0,5)
transDataToFig1 = ax.transData+fig1.transFigure.inverted()
for ix,iy in zip(x,y):
    inDots = ax.transData.transform((ix,iy))
    inFigIndirect = fig1.transFigure.inverted().transform(inDots)
    inFigDirect = transDataToFig1.transform((ix,iy))
    print inDots,"->",inFigIndirect," or ",inFigDirect

fig1.savefig('scatterPos1.png')

由于(1)轴横跨整个图形,(2)轴限制设置为0到5,(3)图形尺寸设置为5x5和100点/英寸,然后一个轴单位对应于100个像素。输出确认了这一点:

[ 100.  100.] -> [ 0.2  0.2]  or  [ 0.2  0.2]
[ 200.  300.] -> [ 0.4  0.6]  or  [ 0.4  0.6]
[ 400.  200.] -> [ 0.8  0.4]  or  [ 0.8  0.4]

上面的代码还向您展示了如何从dpi到数字单位(bbox中的值,介于0和1之间),它提供了一个变换管道的示例(请参阅上面链接的教程)。作为参考,这是结果图:

enter image description here

现在,如果您创建具有子图的第二个图形,则该过程仍然有效,但像素值不是特殊的。以此附加代码为例:

fig2=plt.figure(figsize=(5,5),dpi=100)
ax1 = fig2.add_subplot(121)
ax2 = fig2.add_subplot(122)
ax1.scatter(x,y)
ax1.set_xlim(0,5)
ax2.set_ylim(0,5)
ax2.plot(range(10))

transDataToFig2 = ax1.transData+fig2.transFigure.inverted()
for ix,iy in zip(x,y):
    inDots = ax1.transData.transform((ix,iy))
    inFigIndirect = fig2.transFigure.inverted().transform(inDots)
    inFigDirect = transDataToFig2.transform((ix,iy))
    print inDots,"->",inFigIndirect," or ",inFigDirect

fig2.savefig('scatterPos2.png')

这导致了这个数字:

enter image description here

这个输出:

[  97.72727273  116.66666667] -> [ 0.19545455  0.23333333]  or  [ 0.19545455  0.23333333]
[ 132.95454545  383.33333333] -> [ 0.26590909  0.76666667]  or  [ 0.26590909  0.76666667]
[ 203.40909091  250.        ] -> [ 0.40681818  0.5       ]  or  [ 0.40681818  0.5       ]

请注意,在这种情况下,变换对您使用的轴敏感。我使用了轴ax1,因为它是散点图,与xy中存储的点相对应。

这些示例与您想要做的不同。你有像素的x,y位置,你想看看选择了什么点。这只是transData的反转变换,它通常(未反转)获取数据单元中的点并将它们返回到显示单位(像素)中的点。每个轴都有自己唯一的transData,它对轴限制很敏感。

例如,如果我在位置(120,480)处模拟鼠标点击(以像素为单位),那么每个子图都会将其转换为不同的数据坐标,如下所示:

click = (120,480)
print "Click ",click," transforms into:"
print ax1.transData.inverted().transform(click)," for axes 1"
print ax2.transData.inverted().transform(click)," for axes 2"

这导致:

Click  (120, 480)  transforms into:
[ 1.63225806  3.725     ]  for axes 1
[-7.86193548  9.675     ]  for axes 2

请注意,ax2(第二个子图)的转换会导致负x位置。这是因为像素位置(120,480)在第二个子图的x极限之外。