Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get the same output of voronoin of MATLAB by scipy.spatial.Voronoi of Python

I use voronoin of MATLAB to judge the connection between cells, and I want to convert this function to Python.

When I use scipy.spatial.Voronoi of Python, the output is a little different. For example, I used the same input for MATLAB and Python as you can see in the next code.

MATLAB:

seed = [ 17.746    -0.37283   -0.75523;
         6.1704     1.3404     7.0341;
        -7.7211     5.4282     4.5016;
         5.8014     2.1252    -6.2491;
       -16.047     -2.8472    -0.024795;
        -2.2967    -6.7334     0.60707]
[vvern_mat, vceln_mat] = voronoin(seed);

Python:

import numpy as np
from scipy.spatial import Voronoi
seed = np.array([[ 17.746   ,  -0.37283 ,  -0.75523 ],
       [  6.1704  ,   1.3404  ,   7.0341  ],
       [ -7.7211  ,   5.4282  ,   4.5016  ],
       [  5.8014  ,   2.1252  ,  -6.2491  ],
       [-16.047   ,  -2.8472  ,  -0.024795],
       [ -2.2967  ,  -6.7334  ,   0.60707 ]])
vor = Voronoi(seed)
vvern_py = vor.vertices
vceln_py = vor.regions

The output is as follows:

MATLAB:

vvern_mat = 
        Inf       Inf       Inf
        -6.9386    1.7980   -7.7861
        -15.9902  -20.8031   50.1840
        29.5016  106.3690    5.9214
        8.6816   -6.5899   -0.1741
        -0.2027    2.1210    0.5874

vceln_mat = 
        1     4     5
        1     3     4     5     6
        1     2     3     4     6
        1     2     4     5     6
        1     2     3
        1     2     3     5     6

Python:

vvern_py = array([[ -6.93864391,   1.79801934,  -7.78610533],
                  [-15.9902125 , -20.80310202,  50.1840397 ],
                  [ 29.501584  , 106.36899584,   5.92137852],
                  [  8.68156407,  -6.58985621,  -0.17410448],
                  [ -0.20266123,   2.12100225,   0.58735065]])

vceln_py = [[],
            [-1, 0, 2, 3, 4],
            [-1, 2, 3],
            [-1, 0, 1],
            [-1, 0, 1, 2, 4],
            [-1, 1, 2, 3, 4],
            [-1, 0, 1, 3, 4]]  

When you focus on vceln, you would notice the values are the same between MATLAB and Python because you can get vceln_mat by adding two to vceln_py. However, the line order is different, and I had difficulty converting vceln_py to vceln_mat.

I thought I could solve this problem by applying Qhull options of MATLAB to Python, but I couldn't get the same output. (About options of voronoin: https://jp.mathworks.com/help/matlab/ref/voronoin.html?lang=en#bqurvsm-1) If anyone can solve this problem, I would really appreciate.

like image 789
smop Avatar asked Nov 07 '22 11:11

smop


1 Answers

The ordering of the lists in vor.regions can be arbitrary. However, you can get the information of which region is associated with which entry point via the vor.point_region attribute. The scipy.spatial.Voronoi documentation says

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

So you have to order vor.regions according to that information in vor.point_region

# Find point coordinate for each region
sorting = [np.where(vor.point_region==x)[0][0] for x in range(1, len(vor.regions))]
# sort regions along coordinate list `sorting` (exclude first, empty list [])
sorted_regions = [x for _, x in sorted(zip(sorting, vor.regions[1:]))]

sorted_regions = [[-1, 2, 3],
                  [-1, 1, 2, 3, 4],
                  [-1, 0, 1, 2, 4],
                  [-1, 0, 2, 3, 4],
                  [-1, 0, 1],
                  [-1, 0, 1, 3, 4]]

Like this you obtain the ordering of the MATLAB voronoin function, which apparently does this sorting already intrinsically.

To get also the same numerical values you can calculate (as you mentioned already do)

# PseudoCode 
vceln_py = vceln_mat - 2

However, the reason for that seems to be documented neither in scipy.spatial.Voronoi, voronoin nor in the qhull documentation.

like image 183
gehbiszumeis Avatar answered Nov 14 '22 09:11

gehbiszumeis