Python Matplotlib:散点图圆的质心

Python Matplotlib:散点图圆的质心,python,matplotlib,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: fo

我有一个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个数组,但这对我来说毫无意义,因为只有三个圆圈,我似乎找不到任何有助于解释这一点的文档:

(数组([0.,-0.5]),1)

(数组([0.13260155,-0.5,0.25978994,-0.44731685,0.355339, -0.35539]),4)

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

(数组([0.5,0.13260155,0.44731685,0.25978994,0.355339, 0.35539]),4)

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

(数组([-0.13260155,0.5,-0.25978994,0.44731685,-0.355339, 0.35539]),4)

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

(数组([-0.5,-0.13260155,-0.44731685,-0.25978994,-0.355339, -0.35539]),4)

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

(数组([0.,-0.5]),79)


谢谢

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

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

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之间),并提供了一个变换管道的示例(请参见上面链接的教程)。作为参考,这是结果图:

现在,如果制作第二个具有子图的图形,该过程仍然有效,但像素值没有那么特殊。以此附加代码为例:

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')
其结果如下:

这个输出:

[  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,因为它具有散点图,对应于存储在
x
y
中的点

这些示例与您听起来想要做的不同。你有x,y像素的位置,你想看看什么点被选中。这就是
transData
的反转变换,通常(未反转)以数据单位获取点,并将它们返回到以显示单位(像素)表示的点。每个轴都有自己独特的
transData
,这对轴限制非常敏感

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

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位置。这是因为像素位置(120480)超出了第二个子图的x限制。

如果不清楚,您似乎不愿意接受答案:当我只有一个子图时,这非常有效,当我处理多个子图时,我应该做些什么?当我比较inFigIndirect和inFigDirect时得到的数字非常不同,因此我不确定如何继续。任何帮助都将不胜感激。谢谢@这是因为我对
transDataToFig
transform的定义有问题。它的定义顺序错误,因此未正确计算inFigDirect的
。上面这个特殊的例子表现得很好,但你是对的,当我转到一个不那么强迫的例子时,它失败了。我添加了进一步的示例和讨论。请让我知道这是否有用。是的,这非常有用。再次感谢你的帮助。