Hi @lalit ,
You can add a trace of type go.Volume to your Figure, to point out that a double integral over the chosen rectangle is a volume (in the classical sense).
I modified your function, adding 4 instead of 2, because with 2 the graph is too close to z-plane and the filled volume isnβt so visible in this case.
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
f = lambda x,y: np.cos(x)+np.sin(y)+4
#surface
x, y = np.meshgrid(
np.linspace(-5, 5, 100),
np.linspace(-5, 5, 100)
)
z = f(x,y)
#patch of surface
lower_x, upper_x = -1, 2
lower_y, upper_y = -2, 4
int_x, int_y = np.meshgrid(
np.linspace(lower_x, upper_x, 50),
np.linspace(lower_y, upper_y, 70)
)
int_z = f(int_x,int_y)
fig= go.Figure()
fig.add_surface(x=x[0], y=y[:, 0], z=z, showscale=False,
colorscale=px.colors.sequential.Pinkyl, opacity=0.6)
fig.add_surface(x=int_x[0],y=int_y[:, 0],z=int_z, showscale=False, colorscale=px.colors.sequential.Agsunset, opacity=1)
lower_z= 0
upper_z= int_z.max()
X, Y, Z = np.mgrid[lower_x:upper_x:50j, lower_y:upper_y:50j, lower_z:upper_z:75j]
vals = Z-f(X,Y)
fig.add_volume(x=X.flatten(), y=Y.flatten(), z=Z.flatten(), value= vals.flatten(),
surface_show=True, surface_count=2,
colorscale=[[0, px.colors.sequential.Agsunset[4]],[1.0, px.colors.sequential.Agsunset[4]]],
showscale=False,
isomin=-upper_z, isomax=0) #isomin=-upper_z corresponds to z=f(x,y)-upper_z, and isomax=0, to z=f(x,y)
fig.update_layout(height=600, width=600, scene_zaxis_range=[0, upper_z+0.5],
scene_camera_eye=dict(x=1.85, y=1.85, z=0.7))
The go.Volume trace is memory consumming, because X,Y Z and vals are 3d arrays defined by np.mgrid.
How is defined this volume?
Within the parallelipiped [lower_x, upper_x] x[lower_y, upper_y] x[lower_z, upper_z]
are drawn two surfaces z=f(x,y)+c, where c must be chosen such that to get as the upper boundary of your volume the surface of equation int_z=f(int_x,int_y)
, and as a lower boundary, its projection onto the z-plane. For the second surface we perform a trick: choose c such that only the maximum value belong to z=0.
The surface int_z=f(int_x, int_y)-upper_z
meets this requirement. Hence we are setting isomin=-upper_z, isomax=0
, in the go.Volume definition.