Home > database >  how does the np.index_exp[] work in the 3D voxel / volumetric plot with rgb colors example
how does the np.index_exp[] work in the 3D voxel / volumetric plot with rgb colors example

Time:11-17

I am reading the example: https://matplotlib.org/stable/gallery/mplot3d/voxels_rgb.html#sphx-glr-gallery-mplot3d-voxels-rgb-py about creating a 3d sphere. But I don't understand how the indexing works in the example. Can any one help me to understand. Thanks

> def midpoints(x):
> sl = ()
> for i in range(x.ndim):
>>    x = (x[sl   np.index_exp[:-1]]   x[sl   np.index_exp[1:]])
>>    sl  = np.index_exp[:]
>>    print(np.index_exp[:-1])
>>    print(x[np.index_exp[:-1]])
I know the "index_exp[:-1]" returns (slice(None,None,-1),) and "x[index_exp[:-1]]" will give result like this:
[[[0 0 0],
  [0 0 0],
  [0 0 0]],
[[1 1 1],
  [1 1 1],
  [1 1 1]]]

But I don't understand how the ```x[index_exp[:-1]]``` in the for loop only shows:
[[[1 1 1],
  [1 1 1],
  [1 1 1]]]

CodePudding user response:

In the example, x, is one of the (17,17,17) arrays produced by

In [208]: r, g, b = np.indices((17, 17, 17)) / 16.0
     ...: rc = midpoints(r)
     ...: gc = midpoints(g)
     ...: bc = midpoints(b)

indices is like meshgrid and mgrid, creating grid arrays.

I haven't used np.index_exp, but I see it's the same as np.s_, except it always returns a tuple

In [225]: x = r.copy()
In [226]: () np.index_exp[:-1]    # so this tuple can joined with sl
Out[226]: (slice(None, -1, None),)
In [227]: x[() np.index_exp[:-1]].shape
Out[227]: (16, 17, 17)
In [228]: x[:-1].shape
Out[228]: (16, 17, 17)

so

x = (x[sl   np.index_exp[:-1]]   x[sl   np.index_exp[1:]])/2.0

for the initial sl, this is

x = (x[:-1]   x[1:])/2.0

x[1:]-x[:-1] is widely used to take the difference between adjacent elements, np.diff. Here it just acts on the first dimension (of 3). So this is just the mean of adjacent points.

The next bit just adds a [:] slice to sl:

In [230]: sl  = np.index_exp[:]
In [231]: sl
Out[231]: (slice(None, None, None),)
In [232]: sl   np.index_exp[:-1]
Out[232]: (slice(None, None, None), slice(None, -1, None))

So this is doing

 x[:, :-1]     # which should be a (16,16,17) array

and the next iteration x[:,:, :-1] # (16,16,16)

This r varies only in the first dimension, so can compare its values with the midpoints with:

In [249]: r1 = midpoints(r)
In [250]: r[:5,0,0]
Out[250]: array([0.    , 0.0625, 0.125 , 0.1875, 0.25  ])
In [251]: r1[:4,0,0]
Out[251]: array([0.03125, 0.09375, 0.15625, 0.21875])

So the use index_exp just allows them to write the (x[:-1] x[1:])/2 averaging in a general way that applies to all 3 dimensions the r, g.b arraus/

  • Related