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

yb3bgrhw  于 2023-04-22  发布在  Python
关注(0)|答案(2)|浏览(162)

我正在用三个正方形数组xyz构建一个球体。每个数组的形状是(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 形状。我通过展平xyz,在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]

现在,每个数组都有shape(7900,1);此外,np.sqrt(7900)=88.8819,因此在不添加或进一步移除点的情况下,1D阵列不能被重塑为正方形阵列。
我想从这些点创建一个类似的曲面。如果我尝试使用相同的绘图方法(go.Surface),则不会显示任何内容,并且go.Mesh3d

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

也会产生一个没有表面的空白图像。我如何使用Plotly来显示1D数组的3D表面,类似于我能够为球体产生的表面?

8qgya5xd

8qgya5xd1#

如果你指的是由x,y z定义的形状为(m,n)的曲面,其中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))

如果你想到了另一种情况,请给予一个最小的例子。

umuewwlo

umuewwlo2#

首先,似乎你正在使用一个旧的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)

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

pip install plotly --upgrade

相关问题