使用 Python 中的非正方形 X、Y、Z 数组在 Plotly 中生成网格图

问题描述 投票:0回答:2

我正在构建一个包含三个正方形阵列的球体,

x
y
z
。每个数组的形状是 (100,100)(即
x.shape = (100, 100)
),我可以用 Plotly 绘制曲面:

import numpy as np
import plotly.graph_objs as go
from plotly.offline import plot

r = 1000
u, v = np.mgrid[0:2 * np.pi:100j, 0:np.pi:100j]
x = np.cos(u) * np.sin(v)
y = np.sin(u) * np.sin(v)
z = np.cos(v)

# Plotting layout
titlecolor = 'white'
bgcolor = 'black'
noaxis = dict(showbackground=False, showgrid=False, showline=False, 
              showticklabels=False, ticks='', title='', zeroline=False)

layout = go.Layout(autosize=True,
         titlefont = dict(family='Courier New', color=titlecolor),
         showlegend = False,
         scene = dict(xaxis=noaxis, yaxis=noaxis, zaxis=noaxis,
                      aspectmode='auto'),
         paper_bgcolor = bgcolor,
         plot_bgcolor = bgcolor)

fig = go.Figure(data=go.Surface(x=x, y=y, z=z, opacity=0.2), layout=layout)
plot(fig, validate = False, auto_open=True)

产生

但是现在,假设我不想显示整个球体——相反,我想删除 Z > 0.8 的点,并显示 that 形状。为此,我将

x
y
z
展平,在
z
中找到索引,其中
z>0.8
,然后从所有三个数组中删除这些索引:

# Remove points where z > 0.8
x,y,z = [i.flatten() for i in [X,Y,Z]]
rmvidx = np.where(z>0.8)
x = [np.delete(x,j) for j in rmvidx][0]
y = [np.delete(y,j) for j in rmvidx][0]
z = [np.delete(z,j) for j in rmvidx][0]
# Add in new axis
x = x[:,np.newaxis]
y = y[:,np.newaxis]
z = z[:,np.newaxis]

现在,每个数组的形状都是 (7900,1);此外,

np.sqrt(7900)=88.8819
,因此一维数组不能在不添加或进一步删除点的情况下重新整形为方形数组。

我想从这些点创建一个相似的表面。如果我尝试使用相同的绘图方法(

go.Surface
),则什么也没有显示,并且
go.Mesh3d

fig = go.Figure(data=go.Mesh3d(x=x, y=y, z=z, opacity=0.2), layout=layout)

也会产生没有表面的空白图像。我如何使用 Plotly 显示 1D 阵列的 3d 表面,类似于我能够为球体生成的表面?

python-3.x plotly visualization mesh surface
2个回答
0
投票

如果您指的是由形状 (m, n) 的 x, y z 定义的表面,且 m≠ n,则 go.Surface 和 go.Mesh3d 的工作方式与形状 (m, m) 的情况相同:

import numpy as np
from numpy import pi, sin, cos
u = np.linspace(0, 1, 50)
v = np.linspace(0, 2*pi, 100)
u, v = np.meshgrid(u,v)
x = u*cos(v)
y = u*sin(v)
z = u**2
#x, y z are of shape  (100, 50)
fig = go.Figure(go.Surface(x=x, y=y, z=z))

或作为三角面:

import numpy as np
from numpy import pi, sin, cos
from scipy.spatial import Delaunay
u = np.linspace(0, 1, 50)
v = np.linspace(0, 2*pi, 100)
u, v = np.meshgrid(u,v) #u, v have shape(100, 50)
u1,v1 = u.flatten(),v.flatten()
points2D=np.vstack([u1,v1]).T
x = u1*cos(v1)
y = u1*sin(v1)
z = u1**2
tri= Delaunay(points2D)
i, j, k = tri.simplices.T
fig = go.Figure(go.Mesh3d(x=x, y=y, z=z, i=i, j=j, k=k,intensity=z))

如果您有其他情况,请举一个最小的例子。


0
投票

首先,您似乎使用的是旧的 Plotly 版本。一个更简单的编码器,可以与从 2020 年开始发布的任何版本一起运行:

import numpy as np
import plotly.graph_objects as go

u, v = np.mgrid[0:2 * np.pi:100j, 0:np.pi:100j]
x = np.cos(u) * np.sin(v)
y = np.sin(u) * np.sin(v)
z = np.cos(v)
axes_off=dict(xaxis_visible=False, yaxis_visible=False, zaxis_visible=False)
fig = go.Figure(go.Surface(x=x, y=y, z=z, colorscale="matter_r"))
fig.update_scenes(dict(**axes_off))
fig.show()

不是删除一些元素,只是使它们在

np.nan
上的设置无效:

z[np.where(z>0.8)]=np.nan
fignew=go.Figure(go.Surface(x=x, y=y, z=z, colorscale="matter_r"))
fignew.update_scenes(dict(**axes_off))
fignew.update_layout(width=500, height=500, font_size=11)

第二:要安装新的 ploy 版本,请使用以下命令:

pip install plotly --upgrade
© www.soinside.com 2019 - 2024. All rights reserved.