我有一个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)
由于
答案 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之间),它提供了一个变换管道的示例(请参阅上面链接的教程)。作为参考,这是结果图:
现在,如果您创建具有子图的第二个图形,则该过程仍然有效,但像素值不是特殊的。以此附加代码为例:
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
,它对轴限制很敏感。
例如,如果我在位置(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极限之外。