# plotting f(x,y)=x/y also plots the plane y=0 instead of being undefined

when i plot f(x,y)=x/y plot3D additionally draws the plane y=0... thus the level curves become crosses instead of lines ... Here is my code :

var('x','y','z')
f(x,y)=x/y
from sage.plot.plot3d.plot3d import axes
P = axes(2, color='black')
P=plot3d(f(x,y),(x,-4,4),(y,-4,4),color='khaki',opacity=0.7)
levels=[-3,-2,-1,0,1,2,3]
epsilon=0.1
for h in levels:
P+=implicit_plot3d(f(x,y)==h,(x,-4,4),(y,-4,4),(z,h,h+epsilon),color='red')
P.show()


Additionally i would like to specify the range of z (i.e. between -10 and 10), and i cannot find how to do that in the manuel...

edit retag close merge delete

You can restrict the z-range a posteriori like this

....: P=plot3d(f(x,y),(x,-4,4),(y,-4,4),color='khaki',opacity=0.7)

( 2020-11-05 21:10:12 +0200 )edit

Sort by » oldest newest most voted

An explanation rather than a solution:

This is best understood by extrapolation from the <2D case.

sage: plot(1/x,(x, -4,4), ymin=-4, ymax=4, axes=False, frame=True)


plots a (section of) hyperbola and an almost vertical line around x=0. this is a byproduct of the protting algorithm, hich computes plot_points points of the curve and interpolates a curve between them. The almost vertical line is what remains of the interpolated segment between the lats point with x<0 and the first point with x>0after clipping in the plot limits. This artefact can be avoided by requestiong plot's algorithm to fetect the sign changes with the option detect_poles:

sage: plot(1/x,(x, -4,4), ymin=-4, ymax=4, axes=False, frame=True, detect_poles=True)


Similarly, plot3d (and implicit_plot3d) compute plot_points^2 surface points and interpolates surface elements between them. The plane segments you see are the clipped remains of these surface elements around y=0.

Unfortunately, these 3D plot functions do not have a detect_poles option (which would be somewhat nontrivial to write in the 3D case, anyway...). And I am not aware of any easy way to "clip off" these surface elements straddling the discontinuity.

In this specific case, one could work around the difficulty by parametrically plotting the function in cylindrical or spherical coordinates, avoiding the discontinuity region. An approximation can be obtained by :

parametric_plot3d([r*cos(theta),r*sin(theta),max_symbolic(-10,min_symbolic(10,r*tan(theta)))],
(r,0,4),(theta,-pi/2+1e-3,pi/2-1e3)) +
parametric_plot3d([r*cos(theta),r*sin(theta),max_symbolic(-10,min_symbolic(10,r*tan(theta)))],
(r,0,4),(theta,-3*pi/2+1e-3,-pi/2-1e-3))


which can be clipped off afterwards (I can't remember how ATM, but this exists...).

HTH,

more