I would like to code the below figure (a latent variable model) in tikz. However all my attempts to recreate the figure fail despite reading the tikz manual, see code below.
How can I align the nodes and arrows more to the left?
% latent variable model
\begin{tikzpicture}[transform shape, node distance=2cm,
roundnode/.style={circle, draw=black, very thick, minimum size=7mm},
squarednode/.style={rectangle, draw=black, very thick, minimum size=5mm},
arrow/.style = {semithick,-Stealth}
]
%Nodes
\node[roundnode](latent)[align=center]{T};
\node[squarednode](X2)[left=1.2cm of latent, align=center]{X2};
\node[squarednode](X1)[above= 0.5cm of X2, align=center]{X1};
\node[squarednode](X3)[below= 0.5cm of X2, align=center]{X3};
%Letters
\node[text width=3cm, left=1cm of X1]{e1};
\node[text width=3cm, left=1cm of X2]{e2};
\node[text width=3cm, left=1cm of X3]{e3};
%Arrows
\draw[arrow] (T) -- ["\lambda1"] (X1);
\draw[arrow] (T) -- ["\lambda2"] (X2);
\draw[arrow] (T) -- ["\lambda3"] (X3);
\draw[arrow] (e1) -- (X1);
\draw[arrow] (e2) -- (X2);
\draw[arrow] (e3) -- (X3);
\end{tikzpicture}
Best Answer
There are a couple of problems with your code.
First of all the syntax for specifying a node is
The only thing that is mandatory is
{<node text>}
, so\node {foo};
is perfectly valid.If you want to draw a line/arrow to/from a node, it is the
<name>
that you use as a coordinate, not the<node text>
. You haveso in order to draw a line from the node containing the text
T
, you have to use\draw (latent) ...
. The same goes for thee1
/e2
/e3
nodes.I would also say that it would be better to have all the settings in the same brackets, i.e.
Except that
align=center
doesn't really do anything here, as you haven't set thetext width
, so I would use justNext point is
\node[text width=3cm, left=1cm of X1]{e1};
. I would remove thetext width
setting here, you don't want the node to be much wider than the text (e1
), do you?There is also a problem in the lines
It looks like you're trying to use the syntax defined by the
quotes
library, but that is intended as a shorthand for labels, and labels belong to nodes. So I think you must doNote I also used math mode, because
\lambda
only works in math mode, and added the number as a subscript.From your image, you probably want
$e_1$
and$X_1$
as well.For the
k
nodes, I added a suggestion in the code below. I added theXk
node belowX3
, but note that I addedyshift=0.5cm
to the settings of theX2
node, to move it up a bit.The code below also shows an example of how you can shorten the code by using a
\foreach
loop.Complete code.