Asymptote 3d plot with contour on top of surface

3dasymptotetikz-3dplot

I'm trying to plot 3D graph with Asymptote. I used a previous post as guidance.

I have well structred X and Y and Z values in 2 files. One with x and y variables and the other file with z matrix. All computations are performed using R. I'm only using Asymptote for plotting.

Below is the Asymptote code that was tried so far:

import three;
import grid3;
import graph3;
import palette;

unitsize(5cm,5cm,5cm);
currentprojection=orthographic(18,17,3);

bool renderPRC = true; 

if(renderPRC) { ...
    // PRC TRUE
    settings.prc=true;
    settings.embed=true;
}
else {
    // RASTERIZE
    settings.outformat="png";
    settings.prc=false;
    settings.render=3;
}

file fic =input("xy_new.csv").line().csv(); 
file fic1 =input("z_new.csv").line().csv();

real[][] z=fic1.dimension(0,100);
real[][] a=fic.dimension(0,2);
real [][] b=transpose(a);

real [] xpt,ypt;
xpt = b[1];
ypt = b[0];
real[][] zpt=-z;

surface s=surface(zpt,xpt,ypt,Spline);
s.colors(palette(s.map(zpart),Rainbow()));
draw(s);

The output that I get is not a 3D file.

enter image description here

I'm expecting something like this:

enter image description here

The above plot was produced using the following R function with same x,y and z values:

plot3D::persp3D(x = x, y = y, z = -1*z, col="grey87",cex.axis=1, cex.lab=1,
        colkey=FALSE, theta=-30,alpha = 1,zlim=c(-500,-240),ylim=c(0.2,5),
        border = "grey50", ticktype="detailed",scale=T,
        contour=list(levels = -1*c(240,242.09,242.3,242.8,243,244,245,246,247,247.5,247.8),side ="z",col="grey39"),
        xlab="$\\sigma$",ylab="$\\xi$", zlab="Log Likelihood",
        lty=0,expand = 0.7)

I have 2 part question:

  1. Why is my Asymptote plot not in 3d?
  2. How can I draw contour on top of surface plot?

Best Answer

Sorry for late, but it is very difficult to have free time and then to contribute on Asymptote question.

Your main problem is unitsize and the difference between x, y, z, ranges. It is why you have such a picture. You then have two possibilitues : modify unitsize or use size3 with IgnoreAspect (which avoids automatic scaling). I also add the contour question.

import grid3;
import graph3;
import palette;
import contour; 
import x11colors; 
//unitsize(2cm,.002cm,.05cm);
size3(300,300,IgnoreAspect);

currentprojection=orthographic(18,17,3);

currentprojection=orthographic(camera=(-15.2232850051446,-32914.6837071317,892.991504793621),
                               zoom=0.822702474791882);

file fic =input("xy_new.csv").line().csv(); 
file fic1 =input("z_new.csv").line().csv();

real[][] z=fic1.dimension(0,100);
real[][] a=fic.dimension(0,2);
real [][] b=transpose(a);

real [] xpt,ypt;
xpt = b[1];
ypt = b[0];
real[][] zpt=-z;

surface s=surface(zpt,xpt,ypt,Spline);
s.colors(palette(s.map(zpart),Rainbow()));
draw(s);


for (int i=0; i<10 ; ++i)
  { real t = -250+i; 
    guide[][] contours = contour(zpt,(0.2,100),(5,5000),new real[]{t},join=operator ..);
    guide3[][] liftedcontours = lift(new real (real x, real y) {return t;}, contours);
    for(guide3 p:liftedcontours[0]){
      draw(p,blue+1bp);
    }
  }

xaxis3(Label("$x$",.1),Bounds,InTicks);
yaxis3(Label("$y$",0.5),Bounds,InTicks);
zaxis3(Label("$z$",0.5),Bounds,InTicks(beginlabel=false));

And then the resultenter image description here