Turn off visibility of axis and grids in python plotly "go.Scatter3d" - python-3.x

import numpy as np
xx= np.array([[ 0, 0, 0], [ 0, 5, 0], [ 4, 5, -4], [ 4, 0, 0], [ 0, 0, -4],
[ 0, 5, -4],[ 4, 5, 0], [ 4, 0, -4], [ 8, 5, -4], [ 8, 0, 0], [ 8, 5, 0],
[ 8, 0, -4], [ 4, 10, -4], [ 4, 10, 0], [ 8, 10, -4], [ 8, 10, 0]])
fig = go.Figure()
fig.add_trace(go.Scatter3d(x=xx[:,2],y=xx[:,0],z=xx[:,1],mode='markers'))
fig.show()
enter image description here
Just want to see the points, removing all axis and gridlines.

You can use scene attribute as follows:
import numpy as np
xx= np.array([[ 0, 0, 0], [ 0, 5, 0], [ 4, 5, -4], [ 4, 0, 0], [ 0, 0, -4],
[ 0, 5, -4],[ 4, 5, 0], [ 4, 0, -4], [ 8, 5, -4], [ 8, 0, 0], [ 8, 5, 0],
[ 8, 0, -4], [ 4, 10, -4], [ 4, 10, 0], [ 8, 10, -4], [ 8, 10, 0]])
fig = go.Figure()
fig.add_trace(go.Scatter3d(x=xx[:,2],y=xx[:,0],z=xx[:,1],mode='markers'))
fig.update_layout(scene = dict(xaxis = dict(showgrid = False,showticklabels = False),
yaxis = dict(showgrid = False,showticklabels = False),
zaxis = dict(showgrid = False,showticklabels = False)
))
fig.show()

Related

how yo get the torch.mode 's output indeces , can details

>>> b
tensor([[ 6, 7, 12, 7, 8],
[ 0, 1, 6, 1, 2],
[ 0, 1, 6, 1, 2],
[ 2, 3, 8, 3, 4],
[ 2, 3, 8, 3, 4],
[ 2, 3, 8, 3, 4],
[10, 11, 16, 11, 12],
[-1, 0, 5, 0, 1],
[-2, -1, 4, -1, 0],
[ 2, 3, 8, 3, 4],
[ 1, 2, 7, 2, 3],
[ 1, 2, 7, 2, 3],
[ 2, 3, 8, 3, 4],
[ 5, 6, 11, 6, 7],
[-2, -1, 4, -1, 0],
[-3, -2, 3, -2, -1],
[-5, -4, 1, -4, -3],
[ 1, 2, 7, 2, 3],
[12, 13, 18, 13, 14],
[-3, -2, 3, -2, -1],
[ 2, 3, 8, 3, 4],
[ 3, 4, 9, 4, 5],
[10, 11, 16, 11, 12],
[-6, -5, 0, -5, -4],
[ 9, 10, 15, 10, 11],
[12, 13, 18, 13, 14],
[-3, -2, 3, -2, -1],
[-2, -1, 4, -1, 0],
[-4, -3, 2, -3, -2],
[-1, 0, 5, 0, 1],
[ 2, 3, 8, 3, 4],
[ 4, 5, 10, 5, 6],
[-1, 0, 5, 0, 1],
[ 5, 6, 11, 6, 7],
[ 7, 8, 13, 8, 9],
[ 3, 4, 9, 4, 5],
[ 2, 3, 8, 3, 4],
[ 4, 5, 10, 5, 6],
[-4, -3, 2, -3, -2],
[ 2, 3, 8, 3, 4],
[-1, 0, 5, 0, 1],
[ 2, 3, 8, 3, 4],
[ 4, 5, 10, 5, 6],
[ 9, 10, 15, 10, 11],
[-1, 0, 5, 0, 1],
[-4, -3, 2, -3, -2],
[ 0, 1, 6, 1, 2],
[ 4, 5, 10, 5, 6],
[ 6, 7, 12, 7, 8],
[-2, -1, 4, -1, 0]])
>>> torch.mode(b, 0)
torch.return_types.mode(
values=tensor([2, 3, 8, 3, 4]),
indices=tensor([20, 20, 20, 20, 20]))
i don't know why indeces is all equal to 20
the details of torch.mode description as below
https://pytorch.org/docs/stable/generated/torch.mode.html#torch.mode
torch.mode(input, dim=- 1, keepdim=False, *, out=None)
Returns a namedtuple (values, indices) where values is the mode value of each row of the input tensor in the given dimension dim, i.e. a value which appears most often in that row, and indices is the index location of each mode value found.
By default, dim is the last dimension of the input tensor.
If keepdim is True, the output tensors are of the same size as input except in the dimension dim where they are of size 1. Otherwise, dim is squeezed (see torch.squeeze()), resulting in the output tensors having 1 fewer dimension than input.
It is because of the way the tensor b is. The row [2, 3, 8, 3, 4] is repeated a lot, so in each column the modes are respectively [2, 3, 8, 3, 4] and more importantly, the mode indices will be equal precisely because the modes occur together; if you look at the row with index 20 (i.e., the 21st row), it is exactly [2, 3, 8, 3, 4].
I am assuming that you constructed b similar to the example in torch.mode which I believe is a poor choice for an example as it leads to confusion like the one you are having.
Instead, consider the following:
>>> b = torch.randint(4, (5, 7))
>>> b
tensor([[0, 0, 0, 2, 0, 0, 2],
[0, 3, 0, 0, 2, 0, 1],
[2, 2, 2, 0, 0, 0, 3],
[2, 2, 3, 0, 1, 1, 0],
[1, 1, 0, 0, 2, 0, 2]])
>>> torch.mode(b, 0)
torch.return_types.mode(
values=tensor([0, 2, 0, 0, 0, 0, 2]),
indices=tensor([1, 3, 4, 4, 2, 4, 4]))
In the above, b has different modes in each column which are respectively [0, 2, 0, 0, 0, 0, 2] and the indices returned by torch.mode are [1, 3, 4, 4, 2, 4, 4]. This makes sense because, for example, in the first column, 0 is the most common element and there is a 0 at index 1. Similarly, in the second column, 2 is the most common element and there is a 2 at index 3. This is true for all columns. If you want the modes of the rows instead, you would do torch.mode(b, 1).

getting values of a torch tensor from a tensor of indices

I apologize in advance for my basics knowledge of pytorch, but this problem stuck me for some time.
Suppose I have a torch tensor u of shape (8,8,1), for example
u = tensor([[0.0000, 0.1429, 0.2857, 0.4286, 0.5714, 0.7143, 0.8571, 1.0000],
[0.0000, 0.1429, 0.2886, 0.4470, 0.5896, 0.7171, 0.8571, 1.0000],
[0.0000, 0.1446, 0.3182, 0.4934, 0.6302, 0.7424, 0.8588, 1.0000],
[0.0000, 0.1470, 0.3154, 0.4734, 0.5974, 0.7258, 0.8603, 1.0000],
[0.0000, 0.1397, 0.2742, 0.4026, 0.5266, 0.6846, 0.8530, 1.0000],
[0.0000, 0.1412, 0.2576, 0.3698, 0.5066, 0.6818, 0.8554, 1.0000],
[0.0000, 0.1429, 0.2829, 0.4104, 0.5530, 0.7114, 0.8571, 1.0000],
[0.0000, 0.1429, 0.2857, 0.4286, 0.5714, 0.7143, 0.8571, 1.0000]])
and a tensor of size (2,8,8) of indices of u that I'm interested in
indices = tensor(
[[[0, 0, 0, 0, 0, 1, 0, 2],
[0, 3, 0, 4, 0, 5, 0, 5],
[0, 0, 0, 0, 0, 1, 0, 2],
[0, 3, 0, 4, 0, 5, 0, 5],
[1, 0, 0, 0, 0, 1, 0, 2],
[1, 3, 1, 4, 1, 5, 1, 5],
[2, 0, 1, 0, 1, 1, 1, 2],
[2, 3, 2, 4, 2, 5, 2, 5]],
[[3, 0, 2, 0, 2, 0, 2, 1],
[3, 2, 3, 3, 3, 4, 3, 5],
[4, 0, 3, 0, 3, 0, 3, 1],
[4, 2, 4, 3, 4, 4, 4, 5],
[5, 0, 5, 0, 4, 0, 4, 1],
[5, 2, 5, 3, 5, 5, 5, 5],
[5, 0, 5, 0, 5, 1, 5, 2],
[5, 3, 5, 4, 5, 5, 5, 5]]])
I would like to have a torch tensor result of the same size of u, but where result[i][j] = u[indices[0][i][j],indices[1][i][j] (example: result[0][0] = u[0][3], result[0][1] = u[3][0], result[4][5] = u[5][0]...)
I tried to use torch.gather but I couldn't manage to make it work at all, I tried changing the .view of the tensors but I couldn't match the dimensions. Is there a way to do this?
Start by repeating u tensor like the size of indices [(8, 8) -> (2,8,8)]. After You can use the gather.
repeated_u = u.unsqueeze(dim=0).repeat(indices.shape[0],1,1)
result = torch.gather(repeated_u, 2, indices)
For presented shapes (u.shape -- (8, 8), indices.shape -- (2, 8, 8)) seems like naive indexing works fine result = u[indices[0], indices[1]]

how to assign non contiguous labels of one numpy array to another numpy array and add accordingly?

I have the following labels
>>> lab
array([3, 0, 3 ,3, 1, 1, 2 ,2, 3, 0, 1,4])
I want to assign this label to another numpy array i.e
>>> arr
array([[81, 1, 3, 87], # 3
[ 2, 0, 1, 0], # 0
[13, 6, 0, 0], # 3
[14, 0, 1, 30], # 3
[ 0, 0, 0, 0], # 1
[ 0, 0, 0, 0], # 1
[ 0, 0, 0, 0], # 2
[ 0, 0, 0, 0], # 2
[ 0, 0, 0, 0], # 3
[ 0, 0, 0, 0], # 0
[ 0, 0, 0, 0], # 1
[13, 2, 0, 11]]) # 4
and add all corresponding rows with same labels.
The output must be
([[108, 7, 4,117]--3
[ 0, 0, 0, 0]--0
[ 0, 0, 0, 0]--1
[ 0, 0, 0, 0]--2
[13, 2, 0, 11]])--4
You could use groupby from pandas:
import pandas as pd
parr=pd.DataFrame(arr,index=lab)
pd.groupby(parr,by=parr.index).sum()
0 1 2 3
0 2 0 1 0
1 0 0 0 0
2 0 0 0 0
3 108 7 4 117
4 13 2 0 11
numpy doesn't have a group_by function like pandas, but it does have a reduceat method that performs fast array actions on groups of elements (rows). But it's application in this case is a bit messy.
Start with our 2 arrays:
In [39]: arr
Out[39]:
array([[81, 1, 3, 87],
[ 2, 0, 1, 0],
[13, 6, 0, 0],
[14, 0, 1, 30],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[13, 2, 0, 11]])
In [40]: lbls
Out[40]: array([3, 0, 3, 3, 1, 1, 2, 2, 3, 0, 1, 4])
Find the indices that will sort lbls (and rows of arr) into contiguous blocks:
In [41]: I=np.argsort(lbls)
In [42]: I
Out[42]: array([ 1, 9, 4, 5, 10, 6, 7, 0, 2, 3, 8, 11], dtype=int32)
In [43]: s_lbls=lbls[I]
In [44]: s_lbls
Out[44]: array([0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4])
In [45]: s_arr=arr[I,:]
In [46]: s_arr
Out[46]:
array([[ 2, 0, 1, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[81, 1, 3, 87],
[13, 6, 0, 0],
[14, 0, 1, 30],
[ 0, 0, 0, 0],
[13, 2, 0, 11]])
Find the boundaries of these blocks, i.e. where s_lbls jumps:
In [47]: J=np.where(np.diff(s_lbls))
In [48]: J
Out[48]: (array([ 1, 4, 6, 10], dtype=int32),)
Add the index of the start of the first block (see the reduceat docs)
In [49]: J1=[0]+J[0].tolist()
In [50]: J1
Out[50]: [0, 1, 4, 6, 10]
Apply add.reduceat:
In [51]: np.add.reduceat(s_arr,J1,axis=0)
Out[51]:
array([[ 2, 0, 1, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[108, 7, 4, 117],
[ 13, 2, 0, 11]], dtype=int32)
These are your numbers, sorted by lbls (for 0,1,2,3,4).
With reduceat you could take other actions like maximum, product etc.

how to assign labels of one numpy array to another numpy array and group accordingly?

I have the following labels
>>> lab
array([2, 2, 2, 2, 2, 3, 3, 0, 0, 0, 0, 1])
I want to assign this label to another numpy array i.e
>>> arr
array([[81, 1, 3, 87], # 2
[ 2, 0, 1, 0], # 2
[13, 6, 0, 0], # 2
[14, 0, 1, 30], # 2
[ 0, 0, 0, 0], # 2
[ 0, 0, 0, 0], # 3
[ 0, 0, 0, 0], # 3
[ 0, 0, 0, 0], # 0
[ 0, 0, 0, 0], # 0
[ 0, 0, 0, 0], # 0
[ 0, 0, 0, 0], # 0
[13, 2, 0, 11]]) # 1
and add the elements of 0th group, 1st group, 2nd group, 3rd group?
If the labels of equal values are contiguous, as in your example, then you may use np.add.reduceat:
>>> lab
array([2, 2, 2, 2, 2, 3, 3, 0, 0, 0, 0, 1])
>>> idx = np.r_[0, 1 + np.where(lab[1:] != lab[:-1])[0]]
>>> np.add.reduceat(arr, idx)
array([[110, 7, 5, 117], # 2
[ 0, 0, 0, 0], # 3
[ 0, 0, 0, 0], # 0
[ 13, 2, 0, 11]]) # 1
if they are not contiguous, then use np.argsort to align the array and labels such that labels of the same values are next to each other:
>>> i = np.argsort(lab)
>>> lab, arr = lab[i], arr[i, :] # aligns array and labels such that labels
>>> lab # are sorted and equal labels are contiguous
array([0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 3])
>>> idx = np.r_[0, 1 + np.where(lab[1:] != lab[:-1])[0]]
>>> np.add.reduceat(arr, idx)
array([[ 0, 0, 0, 0], # 0
[ 13, 2, 0, 11], # 1
[110, 7, 5, 117], # 2
[ 0, 0, 0, 0]]) # 3
or alternatively use groupby from pandas library:
>>> pd.DataFrame(arr).groupby(lab).sum().values
array([[ 0, 0, 0, 0],
[ 13, 2, 0, 11],
[110, 7, 5, 117],
[ 0, 0, 0, 0]])

How do I calculate all pairs of vector differences in numpy?

I know I can do np.subtract.outer(x, x). If x has shape (n,), then I end up with an array with shape (n, n). However, I have an x with shape (n, 3). I want to output something with shape (n, n, 3). How do I do this? Maybe np.einsum?
You can use broadcasting after extending the dimensions with None/np.newaxis to form a 3D array version of x and subtracting the original 2D array version from it, like so -
x[:, np.newaxis, :] - x
Sample run -
In [6]: x
Out[6]:
array([[6, 5, 3],
[4, 3, 5],
[0, 6, 7],
[8, 4, 1]])
In [7]: x[:,None,:] - x
Out[7]:
array([[[ 0, 0, 0],
[ 2, 2, -2],
[ 6, -1, -4],
[-2, 1, 2]],
[[-2, -2, 2],
[ 0, 0, 0],
[ 4, -3, -2],
[-4, -1, 4]],
[[-6, 1, 4],
[-4, 3, 2],
[ 0, 0, 0],
[-8, 2, 6]],
[[ 2, -1, -2],
[ 4, 1, -4],
[ 8, -2, -6],
[ 0, 0, 0]]])

Resources