[英]Visualizing the permutohedron in 3D plot
我正在尝试使用 plotly、numpy 和 pandas 对python中的 Permutohedron 进行 plot。
这是我当前的代码:
import plotly.express as px
import numpy as np
import itertools
import pandas as pd
order = 4
items = range(1, order+1)
permuted_items = np.array([*itertools.permutations(items)])
def closest_nodes(node, nodes):
# Returns the instances in nodes that are closest to node
nodes = np.asarray(nodes)
dist_2 = np.sum((nodes - node)**2, axis=1)**.5
indices = np.where(dist_2 == dist_2.min())[0]
return nodes[indices]
xyzs = []
colors = []
for i, point in enumerate(permuted_items[:-1]):
closest_points = closest_nodes(point, permuted_items[i+1:])
for c_point in closest_points:
xyzs.extend([point[:3], c_point[:3]])
# Get unique string as color to group above line while plotting
c = str(point) + str(c_point[:3])
colors.extend([c, c])
lines = np.array(xyzs)
x, y, z = lines.T
plotting_data = pd.DataFrame({
"X": x,
"Y": y,
"Z": z,
"color": colors
})
fig = px.line_3d(plotting_data, x='X', y='Y', z='Z', color="color")
fig.show()
但这绘制了一些非常倾斜的东西:
即我在 3d 中显示此形状的方式(通过删除最后一个维度)更改每行的长度,使得每行的长度不为 sqrt(2)。
实际上,这是我追求的形状:
有什么帮助吗?
在这种情况下,您需要将点投影到 3D 空间,而不是省略第四个坐标。 此处提供了 3x4 矩阵变换
https://blogs.mathworks.com/graphics/2016/01/29/tiling-hexagons-and-other-permutohedra/
工作代码:
import plotly.express as px
import numpy as np
import itertools
import pandas as pd
order = 4
items = range(1, order+1)
permuted_items = np.array([*itertools.permutations(items)])
#Project the points onto 3D space--
A = np.array([[np.sqrt(2)/2, -np.sqrt(2)/2, 0, 0],\
[np.sqrt(6)/6, np.sqrt(6)/6, -np.sqrt(2/3), 0],\
[np.sqrt(12)/12, np.sqrt(12)/12, np.sqrt(12)/12, -np.sqrt(3)/2]])
permuted_items = np.einsum('ik,ak->ai',A,permuted_items)
#----------------------------------
xyzs = []
colors = []
for i, point in enumerate(permuted_items):
d = np.linalg.norm(permuted_items-point[np.newaxis,:],axis=1)
#Inspired by https://stackoverflow.com/questions/31352486/can-numpy-argsort-handle-ties
js = (abs(d - d[d.argsort()[1]])<1e-3).nonzero()[0]
for j in js:
xyzs.extend([point,permuted_items[j]])
# Get unique string as color to group above line while plotting
c = str(point) + str(permuted_items[j])
colors.extend([c, c])
lines = np.array(xyzs)
x, y, z = lines.T
plotting_data = pd.DataFrame({
"X": x,
"Y": y,
"Z": z,
"color": colors,
})
fig = px.line_3d(plotting_data, x='X', y='Y', z='Z', color="color")
fig.show()
请注意,我已经重写了计算最小距离的部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.