Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I will try to answer to questions 3 and 4. I don't really know if you can directly place on the surface the level curves generated by contour_plot or put them on the $xy$ plane. It seems to me that SageMath doesn't have a command or function for doing so. In fact, the plot3d method for 2D graphics doesn't work for contour plots.

However, you can mimic the expected result by playing with colors. To exemplify the method, let us consider the function $$f(x,y) = \frac{2x+3y^2}{(x^2+y^2+1)^2}.$$ Here we have its contour plot in $[-2,2]\times[-2,2]$:

f(x,y) = (2*x+3*y^2) / (x^2+y^2+1)^2
# Contours from z1 to z2. 
# This interval is divided into ni subintervals
z1, z2 = -0.6, 0.8
ni = 10
dz = (z2-z1)/ni
levels = [z1,z1+dz..z2]
curves = contour_plot(f(x,y), (x,-2,2), (y,-2,2), contours=levels, 
                      cmap="jet", colorbar=True)

image description

Please, note that I have explicitly provided the levels to be plotted in order to compare this figure with that of the surface.

Now we plot the surface $z=f(x,y)$ using plot3d. Through a convenient definition of the color function, you can reproduce the very same contours on the surface:

# Surface plot using plot3d
def col2(x,y):
    return float(0.5*dz+floor((f(x,y)-z1)/dz)/ni)
surf = plot3d(f(x,y), (x,-2,2), (y,-2,2), color=(col2,colormaps.jet), plot_points=300)
show(surf, aspect_ratio=[1,1,2])

image description

If we use an orthographic projection, we can then rotate the surface to look at it from above and compare with the contour plot:

show(surf, projection="orthographic")

image description

The same strategy serves to color a plane below the surface, simulating a projection of the contours on the $xy$ plane:

offset = -1.4
plane = plot3d(offset, (x,-2,2), (y,-2,2), color=(col2,colormaps.jet), plot_points=300)

image description

The problem with this approach is that the surface looks jagged, even using a great number of plot points. As an alternative, we can apply implicit_plot3d:

# Surface plot using implicit_plot3d
zmin, zmax = -1, 1
def col3(x,y,z):
    return float(0.5*dz+floor((z-z1)/dz)/ni)
surf_new = implicit_plot3d(z==f(x,y), (x,-2,2), (y,-2,2), (z,zmin,zmax), 
                           color=(col,colormaps.jet), plot_points=[50,50,300])
show(surf_new, aspect_ratio=[1,1,2])

image description

Here we have again a view from above:

show(surf_new, projection="orthographic")

image description

And the surface with the plane:


image description

It seems that implicit_plot3d provides smoother curves on the surface. To get them, it is important to use many points along the $z$-direction.