Я строю сферу с тремя квадратными массивами 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, и показать эту форму. Я делаю это, сглаживая 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 для отображения трехмерной поверхности для одномерных массивов, аналогично тому, что я смог создать для сферы?





Если вы имеете в виду поверхности, определенные 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))
Если вы имеете в виду другой случай, пожалуйста, приведите минимальный пример.
Во-первых, кажется, что вы используете старую версию 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
По вашему запросу я обновил свой исходный вопрос с минимальным примером.