# 3D isometric coordinate system with TikZ

I wish to create the following two graphs with TikZ. Preferably, I would like a simple variable to control the rotation of the graph along the three axes (although, the vertical axis would probably always stay perfectly vertical).

I rough attempt:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
\fill [white] (-1.5,-1/4-.5) rectangle (5.5,5/4+.5);

% Axis
\draw [->, thick] (-1,-1/4) coordinate (in)
-- (0,0/4) coordinate (O)
-- (1,1/4) coordinate (P1)
-- (2,2/4) coordinate (P2)
-- (3,3/4) coordinate (P3)
-- (5,5/4) coordinate (out);

\fill (O) circle (2pt);
\fill (P1) circle (2pt);

\draw [->, thick] ($(O)-(-0.1,0.2)$)  -- ($(P1)-(0.1,0.2)$);
\draw [->, thick] ($(P1)-(-0.1,0.2)$) -- ($(P2)-(0.1,0.2)$);
\draw [->, thick] ($(O)-(-0.1,0.4)$)  -- ($(P2)-(0.1,0.4)$);

\fill (P2) circle (2pt); \fill [white] (P2) circle (1pt);
\fill (P3) circle (2pt); \fill [white] (P3) circle (1pt);
\end{tikzpicture}
\end{document}


Here is my proposal for the first plot (better ask a separate question for the second plot, as it is simpler and all 2D):

\documentclass[tikz, border=2mm]{standalone}
\usetikzlibrary{calc}

\tikzset{
% Arguments: vertex, two points (one on each side), size of the angle mark
3D right angle/.style n args={4}{
help lines,
insert path={
let \p1=($(#2) - (#1)$),
\n1={1/sqrt(({#2}[0]-({#1}[0]))^2 +
({#2}[1]-({#1}[1]))^2 +
({#2}[2]-({#1}[2]))^2)},
\p2=($(\n1*\p1)$),
\p3=($(#3) - (#1)$),
\n2={1/sqrt(({#3}[0]-({#1}[0]))^2 +
({#3}[1]-({#1}[1]))^2 +
({#3}[2]-({#1}[2]))^2)},
\p4=($(\n2*\p3)$) in
($(#1) + {#4}*(\p2)$) -- ++(${#4}*(\p4)$) -- ++($-{#4}*(\p2)$)
}
},
}

\begin{document}

\begin{tikzpicture}[
x={(20:1.2cm)}, y={(90:1.5cm)}, z={(-20:1.2cm)},
my vector/.style={->, blue, very thin},
declare function={x(\theta) = cos(deg(\theta));
y(\theta) = sin(deg(\theta));
z(\theta) = 0.2*\theta;},
]
\begin{scope}[->]
\draw (-1,0,0) -- (4,0,0) node[anchor=200] {$x$};
\draw (0,-2,0) -- (0,2,0) node[above] {$y$};
\draw (0,0,-1) -- (0,0,4) node[anchor=160] {$z$};
\end{scope}

\node[anchor=55] at (0,0) {$O$};

\draw[gray] plot[domain=0:5.3*pi, variable=\theta, samples=100, smooth]
({x(\theta)}, {y(\theta)}, {z(\theta)});

\foreach [evaluate=\n as \theta using pi/2*\n,
evaluate=\n as \z using z(\theta)] \n in {1,2,...,10}
{
\draw[my vector] (0, 0, \z) -- ({x(\theta)}, {y(\theta)}, \z);
\draw[3D right angle={0, 0, \z}
{0, 0, {\z+1}}
{{x(\theta)}, {y(\theta)}, \z}
{0.1}];
}
\end{tikzpicture}

\end{document}


• This drawing is heartwarming :)
– Diaa
Commented Feb 10, 2020 at 16:22

The perspective library has an isometric view key.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{decorations.pathreplacing,calligraphy,perspective,3d}
\begin{document}
\begin{tikzpicture}[isometric view,>=stealth]
\draw[->] (-2,0,0) -- (5,0,0);
\draw[->] (0,2,0) -- (0,-5,0);
\draw[->] (0,0,-4) -- (0,0,4);
\draw plot[domain=0:900,samples=91,smooth]
({2*cos(\x)},{-\x/200},{2*sin(\x)});
\foreach \X in {90,180,...,810}
{\draw[->] (0,-\X/200,0) -- ({2*cos(\X)},{-\X/200},{2*sin(\X)});
\draw  ({0},{-\X/200-0.2},{0}) -- ({0.2*cos(\X)},{-\X/200-0.2},{0.2*sin(\X)})
-- ({0.2*cos(\X)},{-\X/200},{0.2*sin(\X)});}
\begin{scope}[xshift=8cm,decoration={calligraphic brace, amplitude=6pt,raise=0pt}]
\draw[->] (-2,0,0) -- (5,0,0);
\draw[->] (0,0,-4) -- (0,0,4);
\begin{scope}[canvas is xz plane at y=0]
\draw[decorate] (0,0) -- (1.5,0) node[pos=0.4,above=1ex]{$a$};
\draw[decorate] (1.5,0) -- (3,0) node[pos=0.4,above=1ex]{$b$};
\draw[->] (0,-0.2) -- (1.5,-0.2);
\draw[->] (1.5,-0.2) -- (3,-0.2);
\draw[->] (0,-0.4) -- (3,-0.4);
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}


As described in section 64.2 Setting the view of the pgf manual, you have full control over the view angles. Just replacing isometric view by 3d view yields

The only thing I had to adjust is the positions of a and b. You can feed 3d view with arbitrary elevation and azimuth angles. The idea to use right angle marks came from frougon's nice answer (+1). As mentioned in the comments, you can use tikz-3dplot to have the save flexibility, and also can rotate the z axis. In fact, this very code can be used with tikz-3dplot, too.

• This is awesome. I've been studying your code, and I will continue to study it tomorrow as well – I've already implemented parts of it and tweaked it to my liking. But is there a way to colour the brace decorations?
– Matt
Commented Feb 10, 2020 at 23:26
• So I could colour the braces using \draw[decorate, pen colour={<colour>}] …;, but why can't it just take the colour I would normally put in the \draw[decorate, <colour>] …;?
– Matt
Commented Feb 10, 2020 at 23:37
• @Matt If you just use brace instead of calligraphic brace, you can color as you suggest. If you use the "ordinary" brace you do not need to load calligraphy.
– user194703
Commented Feb 10, 2020 at 23:39