# Generate Mandelbrot images using TikZ?

In my thesis that I'm writing on, I'm using a Mandelbrot generator to test an application I've written. To explain a certain problem discussed in the report an actual generated image need to be included.

Since every figure in the report so far has been generated using TikZ, I'm wondering whether I could also generate the Mandelbrot image using TikZ. But would it possible?

-
There's a TikZ library for fractal decorations (30.7 Fractal Decorations) and a Lindenmayer systems library (37 Lindenmayer System Drawing Library) –  Tom Bombadil Aug 25 '12 at 15:44
Heiko Oberdiek posted a Mandelbrot generator in LaTeX at the Programming Puzzels & Code Golf stackexchange: codegolf.stackexchange.com/questions/23423/… –  Martin Heller Mar 25 at 5:50

There's a Mandelbrot set shading in the shadings library:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\end{document}


Displayed with the Acrobat Reader, as the TeXworks PDF previewer did not show high resolution.

The Mandelbrot set is computed and generated by the PDF renderer. The algorithm is written using PostScript commands, PDF supports a subset of Postscript operators, that's why it should be much faster than computing using higher level pgf or TikZ operators.

-
Ha! Well, that was unexpected. ^^ Unfortunately, the image doesn't exactly look like a Mandelbrot set, but cool nonetheless. –  gablin Dec 28 '11 at 17:05
@gablin This could be caused by a low number of iterations, I would expect that a higher number of iterations would be nearer to the exact Mandelbrot set, which would require an infinite number of iterations. –  Stefan Kottwitz Dec 28 '11 at 17:10
@StefanKottwitz Is there any way to increase the iteration count? That looks like 10 or so iterations . . . you get a much better picture even with just 20. –  mrc Nov 15 '13 at 18:53
@mrc Yes, it can be seen in the code of that TikZ library, the number of iteration is fixed but can be extended by changing or redefining the code. –  Stefan Kottwitz Nov 15 '13 at 22:15

For those who are interested in another approach, i.e., using PSTricks:

\documentclass[border=12pt]{standalone}
\usepackage{pst-fractal}

\begin{document}
\end{document}


Compile the code snippet above with xelatex or latex-dvips-ps2pdf sequence.

-
Very cool! How does the pstricks compare to MATLAB or Python in the terms of speed when it comes to things like plotting strange attractors, KAM islands or fractals? How difficult is to generate movie? In MATLAB is for example trivial to generate movie which shows creation of the Lorenz attractor. It is fairly easy to call such movie from the Powerdot slides (written in PSTricks) but I wonder if I could create animation natively which will not require to launch a video player. –  Predrag Punosevac Dec 29 '11 at 2:05
I believe that pstricks does not actually generate the image, it inserts postscript code that does the actual calculation. Which means the speed would depend on your postscript interpreter. When printing such document on a postscript printer, the calculations would be done on the printer. When viewing the resulting dvi or postscript file, the calculations would be done by your dvi or ps viewer at the time of viewing. Perhaps you could first convert from postscript to another format, the calculation would happen then, and view the result later. –  Jan Hlavacek Dec 29 '11 at 2:52
Of course. I meant PostScript and Ghostscript interpreter vs MATLAB or Python. See my post here for getting row PostScript into TeX with command special tex.stackexchange.com/questions/23987/… –  Predrag Punosevac Dec 29 '11 at 4:39

Here is a rather crude solution using luatex. Note that the calculations are done without any optimization, no use of symmetry or any other properties of the Mandelbrot set. Warning: the code takes a while to process even on a fairly fast computer.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{luacode}

\def\escapetime#1#2{\directlua{tex.print(escape_time(#1,#2))}}
\def\mandcolor#1#2{\directlua{mand_color(#1,#2)}}

\begin{document}
\begin{luacode}
local NUMITER=100

point_iter = function (a,b)
local n = 1
local x = a
local y = b
return function ()
if n > NUMITER then return nil end
n = n+1
x,y = x*x - y*y + a, 2*x*y + b
return n, x*x + y*y
end
end

escape_time = function (a,b)
local esc_time
for n, d in point_iter(a,b) do
esc_time = n
if d > 4 then break end
end
return esc_time
end

mand_color = function (a,b)
local etime = escape_time(a,b)
if etime == NUMITER+1 then tex.print("black") else tex.print("red!"..etime) end
end
\end{luacode}
\begin{tikzpicture}[scale=2]
\foreach \x in {-2,-1.99,...,.5}{
\foreach \y in {-1.3,-1.29,...,1.3}{
\draw[\mandcolor{\x}{\y},fill] (\x,\y) +(-.005,-.005) rectangle +(.005,.005);}}
\end{tikzpicture}
\end{document}


This is the resulting image:

The next step would be to use mplib directly from lua to render the picture.

-

I posted a pgfplots solution on TeXwelt.de drawing the Mandelbrot set: Fraktale mit pgfplots. Christian Feuersänger improved it, instead of creating a table (as inspired by Herbert) doing the sampling via \addplot3 and the coloring by surf and shader=interp. Run it with LuaLaTeX.

The complete code:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.8}
\usepackage{luacode}
\begin{luacode}
function mandelbrot(cx,cy, max_iter, max)
local x,y,xtemp,ytemp,squaresum,iter
squaresum = 0
x = 0
y = 0
iter = 0
while (squaresum <= max) and (iter < max_iter)  do
xtemp = x * x - y * y + cx
ytemp = 2 * x * y + cy
x = xtemp
y = ytemp
iter = iter + 1
squaresum = x * x + y * y
end
local result = 0
if (iter < max_iter) then
result = iter
end
-- result = squaresum
-- io.write("" .. cx .. ", " .. cy .. " = " .. result .. " (iter " .. iter .. " squaresum " .. squaresum .. ") \string\n")
tex.print(result);
end
\end{luacode}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
colorbar,
axis equal,
point meta max=30,
tick label style={font=\tiny},
view={0}{90}]
\directlua{mandelbrot(\pgfmathfloatvalueof\x,
\pgfmathfloatvalueof\y,10000,4)}
};
\end{axis}
\end{tikzpicture}
\end{document}

-

I couldn't resist to proposing a MetaPost version. After all, MetaPost is embedded in LuaTeX and thanks to the package luamplib we have direct access to it, so it would be a pity not to take advantage of this fact :-)) All credits must go to Stephan Kottwitz though (and to Herbert previously), since the following code is almost entirely an adaptation of his Lua Code to MetaPost. Without it, drawing this would probably not have been possible to me, since I know too little about fractals.

Notice the call to MetaPost's newly implemented floating point number system by the instruction \mplibnumbersystem{double}. I figure it is necessary, due to the heaviness of the computations.

Caution: it may take several minutes for the following code to compile! (10 min for my 5-year old laptop.)

\documentclass[12pt]{article}
\usepackage{luamplib}
\mplibnumbersystem{double}
\mplibtextextlabel{enable}
\begin{document}
\begin{center}
\leavevmode
\begin{mplibcode}
u := 4cm;
vardef mandelbrot(expr xa, xb, ya, yb, steps, max_iter, maxs) =
save dx, dy, cx, cy, xtemp, ytemp, squaresum, iter; clearxy;
dx := (xb-xa)/steps;
dy := (yb-ya)/steps;
cx := xa;
forever:
exitunless cx <= xb;
cy := ya;
forever:
exitunless cy <= yb;
squaresum := 0;
x:= 0; y:= 0; iter := 0;
forever:
exitunless (squaresum <= maxs) and (iter < max_iter);
xtemp := x**2 - y**2 + cx;
ytemp := 2*x*y + cy;
x := xtemp;
y := ytemp;
iter := iter + 1;
squaresum := x**2 + y**2;
endfor;
if iter >= max_iter: draw u*(cx, cy); fi;
cy := cy + dy;
endfor;
cx := cx + dx;
endfor;
enddef;
beginfig(0);
% Coordinates and marks
xmin = -2; xmax = 0.75; ymin = -1.25; ymax = 1.25; len := 6bp;
draw u*(xmin, ymin) -- u*(xmax, ymin) -- u*(xmax, ymax) -- u*(xmin, ymax) -- cycle;
for i = -1.5 step .5 until .5:
label.bot("$" & decimal i & "$", u*(i, ymin));
draw u*(i, ymin) -- (i*u, ymin*u+len);
draw u*(i, ymax) -- (i*u, ymax*u-len);
endfor;
for j = -1 step 1 until 1:
label.lft("$"&decimal j&"$", u*(xmin, j));
draw u*(xmin, j) -- (xmin*u+len, j*u);
draw u*(xmax, j) -- (xmax*u-len, j*u);
endfor;
% Mandelbrot fractal
pickup pencircle scaled 1bp;
mandelbrot(-2, 1, -2, 2, 500, 1000, 4);
endfig;
\end{mplibcode}
\end{center}
\end{document}


-