# Complex parametric plot in PGFPlots

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:

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.

\RequirePackage{luatex85}
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
% 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;

beginfig(1);
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
enddef;

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;

endfig;
\end{mplibcode}
\end{document}


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.

## Edit

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
enddef;


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
• 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