Back to main page
Back to draw contents

Plotting functions in 3d

This section shows how to draw functions in 3d.


One explicit function.

draw3d(terminal = png,
       explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3));

Another explicit function. In this case, axis and xy-grid are drawn. Note that the user_preamble option is used to draw the grid at z=0 level.

draw3d(explicit(x^2+y^2,x,-1,1,y,-1,1),
       xaxis_width = 2,  xaxis_color = orange,  xaxis_type  = solid,  xaxis=true,
       yaxis_width = 2,  yaxis_color = orange,  yaxis_type  = solid,  yaxis=true,
       zaxis_width = 2,  zaxis_color = blue,    zaxis_type  = solid,  zaxis=true,
       grid=true,
       user_preamble= "set xyplane at 0" );

Hidding surfaces.

draw3d(surface_hide = true,
       terminal     = png,
       explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3));

Global graphics option enhanced3d sets Gnuplot's pm3d mode.

draw3d(surface_hide = true,
       enhanced3d   = true,
       terminal     = png,
       explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3));

The same as before, but without the colorbox.

draw3d(surface_hide = true,
       enhanced3d   = true,
       colorbox     = false,
       terminal     = png,
       explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3));

Changing the color palette to gray.

draw3d(surface_hide = true,
       enhanced3d   = true,
       palette      = gray,
       terminal     = png,
       explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3));

There are some global graphic options for controlling the range and the tics in the colorbox. These features are a contribution by Joan Pau Beltran. They will be present in Maxima 5.19, or you can download the latest version from cvs.

example1:
  gr3d (title = "Controlling color range",
        enhanced3d     = true,
        color          = green,
        cbrange = [-3,10],
        explicit(x^2+y^2, x,-2,2,y,-2,2)) $

example2:
  gr3d (title = "Playing with tics in colorbox",
        enhanced3d     = true,
        color          = green,
        cbtics = {["High",10],["Medium",05],["Low",0]},
        cbrange = [0, 10],
        explicit(x^2+y^2, x,-2,2,y,-2,2)) $

example3:
  gr3d (title = "Logarithmic scale to colors",
        enhanced3d = true,
        color      = green,
        logcb = true,
        logz  = true,
        palette = [-15,24,-9],
        explicit(exp(x^2-y^2), x,-2,2,y,-2,2)) $

draw(example1, example2, example3) $

3d surface with mesh lines.

draw3d (user_preamble  = "set pm3d at s depthorder",
        color          = green,
        explicit(x^2+y^2, x,-2,2,y,-2,2)) $

Setting another color palette. Write ? palette to learn how it works.

draw3d(surface_hide = true,
       enhanced3d   = true,
       palette      = [25,-10,35],
       terminal     = png,
       explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3));

Setting another color palette. Write ? palette to learn how it works.

scene1: gr3d(surface_hide = true,
             enhanced3d   = true,
             palette      = gray,
               explicit(sin(sqrt(x^2+y^2)),x,-5,5,y,-5,5))$

/* A density plot, looking the surface from above */
scene2: gr3d(surface_hide   = true,
             enhanced3d     = true,
             rot_vertical   = 0,
             rot_horizontal = 360,
               explicit(sin(sqrt(x^2+y^2)),x,-5,5,y,-5,5))$

/* Gnuplot experts would prefere to make use of option 'user_preamble' */
scene3: gr3d(surface_hide  = true,
             enhanced3d    = true,
             palette       = gray,
             user_preamble = "set pm3d map",
               explicit(sin(sqrt(x^2+y^2)),x,-5,5,y,-5,5))$

/* Plot all together in a Postscript file */
draw(terminal   = eps_color,
     eps_width  = 10,
     eps_height = 20,
     scene1, scene2, scene3);

By default, when graphics option enhanced3d is set to true, colors depend on the z-values, but when this option is set to an expression, colors depend on the result of this expression and on the actual value of option palette. This is useful for drawing four dimensional plots, where the fourth dimension is given by the color.

draw3d(surface_hide = true,
       terminal     = png,
       enhanced3d   = sin(x*y),  /* note that this expression depends on variables */
                                 /* x and y, as in the explicit object below*/
       explicit(20*exp(-x^2-y^2)-10, x ,-3, 3, y, -3, 3)) $

Another example with two surfaces. Option palette is global, and it can be used only once, since multiple palettes are not allowed in the same plot.

draw3d(surface_hide = true,
       terminal     = eps,
       palette      = gray,
       xu_grid      = 50,
       yv_grid      = 50,

       enhanced3d   = true,  /* equivalent to  enhanced3d = 5*sin(x*y) */
       explicit(5*sin(x*y), x, -5, 5, y, -5, 5),

       enhanced3d   = 5 * sin(v*u),  /* note the variables change, since u and */
                                     /* v are used in the next explicit object */
       explicit(u^2+v^2+10, u, -5, 5, v, -5, 5))$

In this case, enhanced3d is used to draw a shadowed surface. (Thanks to Richard Hennessy for this example.)

f(x,y,z):=z-20*exp(-x^2-y^2)-10;
fn1(x,y):=20*exp(-x^2-y^2)-10;

grad:[diff(f(x,y,z),x),diff(f(x,y,z),y),diff(f(x,y,z),z)] / 
          sqrt(diff(f(x,y,z),x)^2+diff(f(x,y,z),y)^2+diff(f(x,y,z),z));
light:[-1/sqrt(3),-1/sqrt(3),1/sqrt(3)];
dotprod(x,y,z):=grad.light;

draw3d(
    terminal     = eps_color,
    palette      = [4,5,6],
    surface_hide = true,
    xu_grid      = 100,
    yv_grid      = 100,
    colorbox     = false,
    enhanced3d   = dotprod(x,y,fn1(x,y)),
    explicit(fn1(x,y), x ,-3, 3, y, -3, 3)) $

Two explicit functions.

draw3d(key   = "Gauss",
       color = blue,
         explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3),
       yv_grid = 10,
       color   = red,
       key="Plane",
         explicit(x+y,x,-5,5,y,-5,5),
       surface_hide = true);

The same two explicit surfaces as above, but with enhanced colors.

draw3d(enhanced3d   = true,
       palette      = [15,-8,-5],
       explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3),
       explicit(x+y,x,-5,5,y,-5,5)) $

An explicit surface and two parametric curves. Two screen captures

draw3d(color = red,
         explicit(exp(sin(x)+cos(x^2)),x,-3,3,y,-3,3),
       color = blue,
         parametric(cos(5*u)^2,sin(7*u),u-2,u,0,2),
       color = brown,
       line_width = 2,
         parametric(t^2,sin(t),2+t,t,0,2) );

The same as before, but with hidden surfaces, and some more stuff.

draw3d(color = green,
         explicit(exp(sin(x)+cos(x^2)),x,-3,3,y,-3,3),
       color = blue,
         parametric(cos(5*u)^2,sin(7*u),u-2,u,0,2),
       color = brown,
       line_width = 2,
         parametric(t^2,sin(t),2+t,t,0,2),
       surface_hide = true,
       title = "Surface & curves",
       color = red,
         label(["UP",-2,0,3]),
         label(["DOWN",2,0,-3]) );

3D potpourri: a composition with 3d objects.

draw3d(surface_hide = true,
       xlabel       = "x",
       ylabel       = "y",
       zlabel       = "z",
       color        = "light-blue",
         parametric_surface(u**2-v**2,2*u*v,u, u,-3,3,v,-3,3),
       color   = coral,
       xu_grid = 20,
       yv_grid = 10,
         explicit(10+exp(0.3*sin(x^2/10)+0.2*cos(x^3/5)),x,-10,10,y,-10,10),
       color      = black,
       line_width = 2,
       nticks     = 40,
            parametric(15*cos(r),10*sin(r),2*r-10,r,0,4*%pi) );

This is an example of how to plot an explicit function or parametric surface when its domain is not a rectangle. More precisely, the domain of the variables or parameters is given by restrictions of the form

u0 <= u <= u1 and v0(u) <= v <= v1(u),
where

This example is a contribution by Joan Pau Beltran. You will be able to make this plot with Maxima 5.19, or you can download the latest version from cvs.

/* This is an example of uninorm we want to plot:
*/
n(x,y):= 
    if      x<1/4 and y<1/4                 then 2*x*y/(8*x*y-2*x-2*y+1)
    else if x<1/4 and 1/4<=y and y<=3/4     then x
    else if x<1/4 and y>3/4 and x+y<1       then (2*x*y-x)/(8*x*y-6*x-2*y+2)
    else if x<1/4 and y>3/4 and x+y>=1      then (6*x*y-4*x-y+1)/(8*x*y-6*x-2*y+2)
    
    else if 1/4<=x and x<=3/4 and y<1/4               then y
    else if 1/4<=x and x<=3/4 and 1/4<=y and y<=3/4   then 1/4
    else if 1/4<=x and x<=3/4 and y>3/4               then y
    
    else if x>3/4 and y>3/4                 then (6*x*y-4*x-4*y+3)/(8*x*y-6*x-6*y+5)
    else if x>3/4 and 1/4<=y and y<=3/4     then x
    else if x>3/4 and y<1/4 and x+y<1       then (2*x*y-y)/(8*x*y-6*y-2*x+2)
    else if x>3/4 and y<1/4 and x+y>=1      then (6*y*x-4*y-x+1)/(8*y*x-6*y-2*x+2)
$


/* This function reparametrize the non rectangular domain:
    -   f1, f2, f3, are the component of the surface we want to plot
    -   iv is the Independent Variable, the parameter bounded by the two real numbers.
        iv0,iv1 are such numbers.
    -   dv is the Dependent Variable, the parameter bounded by two expressions of the first parameter.
        dv0,dv1 are such expressions.
*/
reparametrize(f1,f2,f3,iv,iv0,iv1,dv,dv0,dv1) := 
    apply( 'parametric_surface, append(
        subst([  iv = 'u , 
                 dv = (1-'v)*subst([iv='u],dv0) + 'v * subst([iv='u],dv1) ],
            [f1,f2,f3]),
        ['u, iv0, iv1, 'v, 0, 1])
    )$



/* And this is the draw command.
Each domain region is plotted separetly to represent the discontinuities of the uninorm:
*/
draw3d(
    terminal=wxt,
    rot_vertical=75, rot_horizontal=330,
    color=blue,
    title="Uninorma",
    xlabel ="x", ylabel="y",
    xtics={0.25,0.75}, ytics= {0.25,0.75}, ztics= 0.25, cbtics=0.25, 
    xu_grid=20, yv_grid=20,
    xrange=[0,1], yrange=[0,1], cbrange=[0,1],
    user_preamble= "set pm3d at b depthorder implicit clip1in corners2color c1;",
         
    reparametrize(x, y, 2*x*y/(8*x*y-2*x-2*y+1),           x,0,0.25, y,0,0.25),
    reparametrize(x, y, x,                                 x,0,0.25, y,0.25,0.75),
    reparametrize(x, y, (2*x*y-x)/(8*x*y-6*x-2*y+2),       x,0.001,0.25, y,0.75,1-x),
    reparametrize(x, y, (6*x*y-4*x-y+1)/(8*x*y-6*x-2*y+2), y,0.75,0.999, x,1-y,0.25),
    
    reparametrize(x, y, y,    x,0.25,0.75,y,0,0.25),
    reparametrize(x, y, 0.25, x,0.25,0.75,y,0.25,0.75),
    reparametrize(x, y, y,    x,0.25,0.75,y,0.75,1),
    
    reparametrize(x, y, (6*x*y-4*x-4*y+3)/(8*x*y-6*x-6*y+5), x,0.75,1, y,0.75,1 ),
    reparametrize(x, y, x,                                   x,0.75,1, y,0.25,0.75),
    reparametrize(x, y, (2*x*y-y)/(8*x*y-6*y-2*x+2),         y,0.001,0.25, x,0.75,1-y),
    reparametrize(x, y, (6*y*x-4*y-x+1)/(8*y*x-6*y-2*x+2),   x,0.75,0.999, y,1-x,0.25)
);

When the elements of a matrix are interpreted as the z-coordinates of the points of a surface, it is possible to draw it by means of the mesh graphic object.

m[i,j] := mod(i,j) $

draw3d(
   color = blue,
   enhanced3d = true,
   mesh(genmatrix(m, 50,50), 0, 0, 1, 1),
   terminal = wxt ) $

Back to main page
Back to draw contents


by Mario Rodríguez Riotorto