# Customizing torus diagram in pgfplots

I'm trying to produce a nice torus diagram to illustrate its parametrization. I have this: but would like to have this: There's a list of things I can't figure out how to do:

1. Move axis labels closer to axes and reverse y axis.
2. Bring positive parts of x and z axes to foreground.
3. Add major and minor radii a and b as illustrated.
4. Crop white space above and to the right.

Here's the current code.

\documentclass{standalone}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[axis equal image,
xlabel=$x$, ylabel=$y$, zlabel=$z$,
axis lines=middle,
xmax=18,ymax=20,zmax=5,
ticks=none,
clip bounding box=upper bound,
colormap/blackwhite]

({(12 + 3 * cos(x)) * cos(y)} ,
{(12 + 3 * cos(x)) * sin(y)},
{3 * sin(x)});
\end{axis}
\end{tikzpicture}
\end{document}

• Note that in your second picture, the axes dont seem right handed. – AJN Apr 16 '16 at 11:29
• use the axis coordinate system to plot minor and major radii. Add this after the \addplot command \draw [thick, blue] (axis cs: 0,0,0) -- (axis cs: 12,0,0); \draw [thick, red] (axis cs: 12,0,0) -- (axis cs: 12,0,3); – AJN Apr 16 '16 at 11:33
• Since Tikz/PGF plots doesn't have real 3D™, it will be better to re draw the X and Z axes using the same axis coordinate convention after the \addplot command just like the radii were drawn. – AJN Apr 16 '16 at 11:37

You can use axis coordinate systems to put regular tikz commands in the pgfplot axes. To bring the axes to foreground, I used the same method to fake the axes. This is not a general solution for other plots.

If you reverse the y axis, the system will not be right handed, and people generally expect axes to be right handed. It is better to bring the x axis to the front and y axis to the right side of the picture (z axis will remain pointed up). \documentclass{standalone}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[axis equal image,
axis lines=middle,
xmax=18,ymax=20,zmax=5,
ticks=none,
clip bounding box=upper bound,
colormap/blackwhite]

({(12 + 3 * cos(x)) * cos(y)} ,
{(12 + 3 * cos(x)) * sin(y)},
{3 * sin(x)});
%use axis coordinate system to draw the radii
\draw [thick, blue] (axis cs: 0,0,0) -- node [yshift=0.5em]{$a$} (axis cs: 12,0,0);
\draw [thick, red] (axis cs: 12,0,0) -- node [xshift=0.5em]{$b$}(axis cs: 12,0,3);

%use axis coordinate system to draw FAKE x, y and z axes
\draw [-latex]  (axis cs: 0,0,0) -- node [pos=0.9, xshift=0.5em]{$z$}(axis cs: 0,0,10);
\draw [-latex]  (axis cs: 0,-15,0) --
node [pos=0.9, xshift=-1em, yshift=0.5em]{$y$}(axis cs: 0,-20,0);
\draw (axis cs: 0,0,0) -- (axis cs: 0,9,0);
\draw (axis cs: 0,0,0) -- (axis cs: -9,0,0);
\end{axis}
\end{tikzpicture}
\end{document}

• Looks great! Switching x and y wouldn't be a problem. (By the way, the x axis seems to be unlabeled in your solution.) – Casimir Apr 16 '16 at 12:03
• I think it may be better you wait a few more hours before accepting this as an answer, as someone with more conversant with pgf plots may propose a better answer; especially if you plan on expanding this to different types of surfaces. – AJN Apr 16 '16 at 12:07
• I don't at present, but if you think a more elegant solution is possible, then that might still be a good idea. – Casimir Apr 16 '16 at 12:13