如何通过Python的scipy.spatial.Voronoi得到MATLAB的Voronoi的相同输出

jqjz2hbq  于 2023-10-14  发布在  Python
关注(0)|答案(2)|浏览(161)

我用MATLAB的voronoin来判断细胞之间的连接,我想把这个函数转换成Python。
当我使用Python的scipy.spatial.Voronoi时,输出有点不同。例如,我对MATLAB和Python使用了相同的输入,如您在下一段代码中所见。
MATLAB:

  1. seed = [ 17.746 -0.37283 -0.75523;
  2. 6.1704 1.3404 7.0341;
  3. -7.7211 5.4282 4.5016;
  4. 5.8014 2.1252 -6.2491;
  5. -16.047 -2.8472 -0.024795;
  6. -2.2967 -6.7334 0.60707]
  7. [vvern_mat, vceln_mat] = voronoin(seed);

Python:

  1. import numpy as np
  2. from scipy.spatial import Voronoi
  3. seed = np.array([[ 17.746 , -0.37283 , -0.75523 ],
  4. [ 6.1704 , 1.3404 , 7.0341 ],
  5. [ -7.7211 , 5.4282 , 4.5016 ],
  6. [ 5.8014 , 2.1252 , -6.2491 ],
  7. [-16.047 , -2.8472 , -0.024795],
  8. [ -2.2967 , -6.7334 , 0.60707 ]])
  9. vor = Voronoi(seed)
  10. vvern_py = vor.vertices
  11. vceln_py = vor.regions

输出如下:
MATLAB:

  1. vvern_mat =
  2. Inf Inf Inf
  3. -6.9386 1.7980 -7.7861
  4. -15.9902 -20.8031 50.1840
  5. 29.5016 106.3690 5.9214
  6. 8.6816 -6.5899 -0.1741
  7. -0.2027 2.1210 0.5874
  8. vceln_mat =
  9. 1 4 5
  10. 1 3 4 5 6
  11. 1 2 3 4 6
  12. 1 2 4 5 6
  13. 1 2 3
  14. 1 2 3 5 6

Python:

  1. vvern_py = array([[ -6.93864391, 1.79801934, -7.78610533],
  2. [-15.9902125 , -20.80310202, 50.1840397 ],
  3. [ 29.501584 , 106.36899584, 5.92137852],
  4. [ 8.68156407, -6.58985621, -0.17410448],
  5. [ -0.20266123, 2.12100225, 0.58735065]])
  6. vceln_py = [[],
  7. [-1, 0, 2, 3, 4],
  8. [-1, 2, 3],
  9. [-1, 0, 1],
  10. [-1, 0, 1, 2, 4],
  11. [-1, 1, 2, 3, 4],
  12. [-1, 0, 1, 3, 4]]

当你专注于vceln时,你会注意到MATLAB和Python之间的值是相同的,因为你可以通过将2加到vceln_py来得到vceln_mat。但是,行顺序是不同的,我很难将vceln_py转换为vceln_mat
我想我可以通过将MATLAB的Qhull选项应用到Python来解决这个问题,但我不能得到相同的输出。(关于voronoin的选项:https://jp.mathworks.com/help/matlab/ref/voronoin.html?lang=en#bqurvsm-1)如果有人能解决这个问题,我将非常感激。

nhaq1z21

nhaq1z211#

vor.regions中列表的顺序可以是任意的。但是,您可以通过vor.point_region属性获取哪个区域与哪个入口点相关联的信息。scipy.spatial.Voronoi documentation说:

  1. point_region: (list of ints, shape (npoints)) Index of the Voronoi region for each input point.

因此,您必须根据vor.point_region中的信息订购vor.regions

  1. # Find point coordinate for each region
  2. sorting = [np.where(vor.point_region==x)[0][0] for x in range(1, len(vor.regions))]
  3. # sort regions along coordinate list `sorting` (exclude first, empty list [])
  4. sorted_regions = [x for _, x in sorted(zip(sorting, vor.regions[1:]))]
  5. sorted_regions = [[-1, 2, 3],
  6. [-1, 1, 2, 3, 4],
  7. [-1, 0, 1, 2, 4],
  8. [-1, 0, 2, 3, 4],
  9. [-1, 0, 1],
  10. [-1, 0, 1, 3, 4]]

像这样,您可以获得MATLAB voronoin函数的排序,它显然已经在本质上完成了这种排序。
为了得到同样的数值,你可以计算(正如你已经提到的)

  1. # PseudoCode
  2. vceln_py = vceln_mat - 2

但是,其原因似乎既没有在scipy.spatial.Voronoivoronoin中也没有在qhull文档中记录。

展开查看全部
emeijp43

emeijp432#

有时vor.regions中有一个空的列表成员,它的索引从vor.point_region中删除,所以len(vor.region) = len(vor.point_region) + 1。在这种情况下,@gehbiszumeis的回答可能会引起错误。我建议使用这行代码:

  1. sorted_regions = [vor.regions[reg] for reg in vor.point_region]

相关问题