# tikz-3dplot and drawing curves and surfaces in 3D

I used the tiikz and tikz-3dplot packages a bit to draw figures in 3D and 3D. I however never yet plotted a mathematical function, and am not sure how to do it.

Could someone please give me a minumal example? The examples I find on the internet are all very complicated plots and drawings.

In particular I would like to plot the curve: z(x) = 1-x^2, on the interval x\in(-1, 1). For the moment I would only need this in 2D, but ultimately it should be a curve in a 3D plot, where I also want to plot the surface z(x,y) = 1-x^2-y.

Thanks for help!

• Please specify what you mean by "mathematical function". Do you want to do a parametric plot, i.e. plot a curve, or a surface (in which case I would think you are much better off with pgfplots).
– user121799
Mar 24, 2019 at 22:50
• Ultimately I am aiming at producing flow plots like the figures on pages 16 and 17 of this paper here: arxiv.org/pdf/gr-qc/0210031.pdf So I need to plot curves with arrows on them, and the curves can lie on surfaces, or within a 3 dimensional body. Mar 24, 2019 at 23:41
• Note: For this sort of thing, the pgfplots package may be a better match. Mar 25, 2019 at 3:28

It is a bit hard to answer this question, but I'll try. Can one draw plots with tikz-3dplot? Certainly, this is why it has this name. You can always draw parametric plots, simply because TikZ can, and then the main purpose of tikz-3dplot is to install an orthographic view. The functions you mention can be plotted e.g. with

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{60}{110}

\begin{tikzpicture}[pics/3d axes/.style={code={%
\draw[-latex] (0,0,0) -- (#1,0,0) node[pos=1.1]{$x$};
\draw[-latex] (0,0,0) -- (0,#1,0) node[pos=1.1]{$y$};
\draw[-latex] (0,0,0) -- (0,0,#1) node[pos=1.1]{$y$};
}}]
\begin{scope}[tdplot_main_coords]
\pic{3d axes=2.5};
\draw plot[variable=\x,domain=-1:1,samples=73,smooth]
(\x,0,{1-\x*\x});
\end{scope}
\begin{scope}[tdplot_main_coords,xshift=5cm]
\pic{3d axes=2.5};
\foreach \Y in {-1,-0.8,...,1}
{\draw plot[variable=\x,domain=-1:1,samples=73,smooth]
(\x,\Y,{1-\x*\x-\Y});}
\foreach \X in {-1,-0.8,...,1}
{\draw plot[variable=\y,domain=-1:1,samples=73,smooth]
(\X,\y,{1-\X*\X-\y});}
\end{scope}
\end{tikzpicture}
\end{document}


These tricks will enable you to reproduce the plots of the arXiv paper you link to rather closely. You also see in the surface plot that it does not hide hidden surfaces. As long as you only draw lines, you will be fine, otherwise consider switching to pgfplots or asymptote.

ADDENDUM: Some arrows. Notice that, as usual with decorations, there might be dimension too large errors, which occur if the curvature is too large. In this case, they would appear if you reinstalled smooth in the plots in which the arrows are added. If you insist on smooth, you need to draw the path twice, once the full thing and once with the arrow up to the position where the arrow head should be.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{arrows.meta,bending,decorations.markings}
\tikzset{%
arc arrow/.style args={%
to pos #1 with length #2}{
decoration={
markings,
mark=at position 0 with {\pgfextra{%
\pgfmathsetmacro{\tmpArrowTime}{#2/(\pgfdecoratedpathlength)}
\xdef\tmpArrowTime{\tmpArrowTime}}},
mark=at position {#1-\tmpArrowTime} with {\coordinate(@1);},
mark=at position {#1-2*\tmpArrowTime/3} with {\coordinate(@2);},
mark=at position {#1-\tmpArrowTime/3} with {\coordinate(@3);},
mark=at position {#1} with {\coordinate(@4);
\draw[-{Stealth[length=#2,bend]}]
(@1) .. controls (@2) and (@3) .. (@4);},
},
postaction=decorate,
}
}

\begin{document}
\tdplotsetmaincoords{60}{110}

\begin{tikzpicture}[pics/3d axes/.style={code={%
\draw[-latex] (0,0,0) -- (#1,0,0) node[pos=1.1]{$x$};
\draw[-latex] (0,0,0) -- (0,#1,0) node[pos=1.1]{$y$};
\draw[-latex] (0,0,0) -- (0,0,#1) node[pos=1.1]{$y$};
}}]
\begin{scope}[tdplot_main_coords]
\pic{3d axes=2.5};
\draw plot[variable=\x,domain=-1:1,samples=73,smooth]
(\x,0,{1-\x*\x});
\end{scope}
\begin{scope}[tdplot_main_coords,xshift=5cm]
\pic{3d axes=2.5};
\foreach \Y in {-1,-0.8,...,1}
{\draw[arc arrow=to pos {0.5-0.25*\Y} with length 2mm]
plot[variable=\x,domain=-1:1,samples=31]
(\x,\Y,{1-\x*\x-\Y});}
\foreach \X in {-1,-0.8,...,1}
{\draw
plot[variable=\y,domain=-1:1,samples=31]
(\X,\y,{1-\X*\X-\y});}
\end{scope}
\end{tikzpicture}
\end{document}


• This was very helpful, thanks a lot! So I suppose as long as I can put my lines in a functional form this should work for me. Allow me one follow up question: is there an easy way to draw arrows on the lines with this approach, similar as in the plots in the PDF? Mar 26, 2019 at 10:42
• @Britzel Yes, sure, e.g. with the arc arrow decoration from tex.stackexchange.com/a/430239/121799, which also bends the arrow.
– user121799
Mar 26, 2019 at 13:07
• And these also work in 3D? Thanks once more! Mar 26, 2019 at 15:57
• @Britzel Yes (up to possible dimension too large errors which however have nothing to do with 3d). I added an example.
– user121799
Mar 26, 2019 at 16:20
• Perfect! Thank you so much for all the help! : ) Mar 26, 2019 at 17:35