Consider the complex variable z = sqrt(x + a1 y) + sqrt(x + a2 y) with x > 0, y in R real, and a1,a2 in C complex. I would like to produce a parametric plot of Re(z) vs. Im(z). It should look something like this:

enter image description here

To my surprise, searching this site for "complex parametric PGFPlots" didn't bring up anything.

Might be that's because (afaik) PGFplots has no notion of complex numbers and no functions Re and Im to isolate real and imaginary parts. So I was thinking about implementing the complex square root as explained by Did in this post on math.stackexchange.com but that would be quite a hassle. Is there a simpler solution?


We can have a go at this with Metapost. I've wrapped this in luamplib but you could easily adapt it for plain mpost. I'm not sure it's a very robust solution, but it might form the basis for some further investigation.

enter image description here

% assume the pair z is a complex number and return the pair corresponding 
% to the complex sqrt
def zsqrt(expr z) = dir 1/2 angle z scaled sqrt(abs(z)) enddef;

    numeric xmin, xmax, ymin, ymax;
    xmin = 0; xmax = 12; ymin = 1; ymax = 3;

    vardef f(expr x,y) = zsqrt((x,0) + (1,1) zscaled (y,0) ) + zsqrt((x,0) + (2,+2) zscaled (y,0)) enddef;
    vardef g(expr x,y) = zsqrt((x,0) - (1,1) zscaled (y,0) ) + zsqrt((x,0) + (2,-2) zscaled (y,0)) enddef;

    vardef edge_path(suffix FUN)(expr xmin, xmax, ymin, ymax, s) =
        for x=xmin step  s until xmax: FUN(x,ymin) .. endfor
        for y=ymin step  s until ymax: FUN(xmax,y) .. endfor
        for x=xmax step -s until xmin: FUN(x,ymax) .. endfor
        for y=ymax step -s until ymin: FUN(xmin,y) .. endfor cycle

    path a, b;
    a = edge_path(f,0,12,1,3,1/4) scaled 1cm;
    b = edge_path(g,0,12,1,3,1/4) scaled 1cm;

    fill a withcolor .8[blue,white]; draw a;
    fill b withcolor .8[red+1/2green,white]; draw b; 

    path xx, yy;

    xx = (1/2 left -- 9 right) scaled 1cm; 
    yy = (7/2 down -- 3 up) scaled 1cm;  
    drawarrow xx;
    drawarrow yy;


Metapost has complex numbers weakly built-in. You can basically treat a pair type as a complex number. The built-in operations abs and angle work as you might expect, and the operation zscaled does complex multiplication.


I have updated the complex sqrt function with a more correct, rather simpler, and more efficient version. The original one was:

vardef sqrtz(expr zz) = 
    save c, r, w;
    numeric r, c;
    pair w;
    r = abs(zz);
    w = zz + (r,0);
    c = sqrt(r)/abs(w);
    w scaled c

which is geometrically sound, but fails with negative real numbers. The replacement is more robust and makes better use of MP's built-in functions. The new one is:

def zsqrt(expr z) = dir 1/2 angle z scaled sqrt(abs z) enddef;

If you are treating pairs as complex numbers, then angle z gives you the argument, and abs z gives you the modulus. dir theta gives a unit vector rotated theta degrees from (1,0), so dir 1/2 angle z gives you a unit vector with half the argument of z, which is then scaled by sqrt(abs z) which is what we want.

Note that if you try to do angle (0,0), MP gives an error that says ! angle(0,0) is taken as zero. In this case this is what we want, but MP stops because of the error. You avoid the error by writing this:

def zsqrt(expr z) = if z=origin: origin else: dir 1/2 angle z scaled sqrt(abs z) fi enddef;

which is probably the best general purpose function.

  • Looks good! I was really hoping for a solution in PGFPlots/TikZ though, since all the other graphics in my project were created that way. – Casimir Feb 16 '17 at 11:24
  • 1
    Thanks. Using standalone means you can produce a PDF that you could include, of course, but perhaps my answer will stimulate the PGFplots mavens to suggest a solution. – Thruston Feb 16 '17 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.