我有一个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)

(数组([-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)

谢谢

最佳答案

我认为您可能对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之间),并提供了转换管道的示例(请参见上面的链接教程)。供参考,以下是结果图:



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

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,因为那是散点图的轴,对应于xy中存储的点。

这些示例与您想要执行的操作不同。您有以像素为单位的x,y位置,并且想要查看选择了哪个点。这就是transData的反变换,通常(un-invert)取数据单位的点并将其返回到显示单位(像素)的点。每个轴都有其自己唯一的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限制之外。

关于python - Matplotlib:散点图圆的质心,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8492890/

10-11 13:26