8

I am trying to draw a probabilistic graphical model using BayesNet, a TikZ library for drawing graphical model in latex. I have tried to insert plates caption - Tasks i, Classes c, workers j, features k - like the first image given below, but I cannot change the position of plate caption. How can I modify second image source code to change all the plates caption position like first image?

enter image description here enter image description here

Here is the code I am using:

\documentclass{article} % For LaTeX2e
\usepackage{nips13submit_e,times}
\usepackage{hyperref}
\usepackage{url}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{bayesnet}

\begin{document}
\begin{tikzpicture}
    % Define nodes
    \node[obs]             (y)      {$y_{i}^{(j)}$};
    \node[obs, right=of y]  (f)      {$f_{ik}^{(j)}$};
    \factor[above=of y,yshift=0.7cm]   {yf}    {Cat} {} {} ; %
    \factor[above=of f,yshift=0.7cm]   {rf}    {Cat} {} {} ;

    \node[latent, left=of yf]  (pi)      {$\pi_{c}^{(j)}$};
    \node[latent, above=of pi, yshift=0.5cm]  (beta)   {$\beta_{c}^{(j)}$};
    \factor[above=of pi, yshift=0.4cm] {pi-f} {left:Dir} {} {} ; %

    \node[latent, above=of yf, xshift=0.8cm, yshift=3cm ]  (t)   {$t_i$};
    \node[latent, above=of t, yshift=0.5cm]  (p)   {$p$};
    \node[latent, right=of p, xshift=0.8cm]  (alpha)   {$\alpha$};
    \factor[above=of t, yshift=0.5cm] {t-f} {left:Dir} {} {} ; %
    \factor[right=of p, xshift=0.5cm] {p-f} {Dir} {} {} ; %

    \node[latent, right=of rf]  (d)      {$z_{k,c}^{(i)}$};
    \node[latent, above=of d, yshift=0.5cm]  (gamma)   {$\gamma_{0,c}^{(i)}$};
    \factor[above=of d, yshift=0.4cm] {d-f} {right:Dir} {} {} ; %

    % Connect the nodes
    \factoredge {gamma}  {d-f}  {d} ;
    \factoredge {alpha}  {p-f}  {p}; %
    \factoredge {p}  {t-f}  {t}; %
    \factoredge {beta}  {pi-f}   {pi} ;
    \factoredge {pi}  {yf}   {y} ;
    \factoredge {d}  {rf}   {f} ;

    \gate {y-gate} {(yf)(yf-caption)} {t}
    \gate {f-gate} {(rf)(rf-caption)} {t}

    % Plates
    \plate [inner sep=0.3cm, xshift=0.1cm, yshift=-0.2cm,color=red] {pA} {(f)(rf)(d)(d-f)} {$k \in K_i$}; %
    \plate [inner sep=0.5cm, xshift=0.2cm, yshift=0.5cm, color=blue] {pC} {(beta)(pi)(d)(gamma)} {C classes};
    \plate [inner sep=0.7cm, xshift=0.3cm, yshift=-0.4cm, color=brown] {pT} {(t)(gamma)(d)(yf)(y)(rf)(f)} {N objects};
    \plate [inner sep=0.5cm, xshift=-0.2cm] {pM} {(beta)(pi)(yf)(y)(rf)(f)} {M workers} ;
    \plate [inner sep=0.2cm, xshift=-0.05cm, yshift=0.15cm] {pJi} {(y)(f)} {$J_i$}

    %minimum height=1.5cm, minimum width=3.0cm, yshift=0.4cm,
\end{tikzpicture}
\end{document}
  • 1
    Welcome! Please make your code compilable by adding a minimal preamble (enough to compile your code) and \begin{document}...\end{document}. If \plate etc. are custom macros, you need to include their definitions. If they are from a library or package, you need to include the code to load them. – cfr Apr 6 '16 at 12:49
  • It is not clear to me which caption you want to change so it wold be god to be a little more explicit. – Andrew Apr 6 '16 at 13:23
  • @Andrew obviously the captions at the bottom, which are overlapping, i.e. N objects, M workers, J_i and $k \in K_i$. – JMP Apr 6 '16 at 13:36
  • off-topic: bravo for this nice tikz diagram in your first question! – ebosi Apr 6 '16 at 13:57
  • @Andrew Yes, the captions at the bottom. – coffeeak Apr 6 '16 at 14:14
7

Hadn't seen that library before, perhaps because it is a third-party library, and not discussed in the TikZ manual. The only documentation seems to be a short readme file, so I had a look at the code of the library itself.

The library file can be found by running kpsewhich tikzlibrarybayesnet.code.tex in a terminal, on my system it is found in /usr/local/texlive/2015/texmf-dist/tex/latex/tikz-bayesnet/tikzlibrarybayesnet.code.tex.

The \plate command is defined there as follows:

\newcommand{\plate}[4][]{ %
  \node[wrap=#3] (#2-wrap) {}; %
  \node[plate caption=#2-wrap] (#2-caption) {#4}; %
  \node[plate=(#2-wrap)(#2-caption), #1] (#2) {}; %
}

The caption is created by the second node, which uses the style plate caption. This style in turn is defined by

\tikzstyle{plate caption} = [caption, node distance=0, inner sep=0pt,
below left=5pt and 0pt of #1.south east]

So you can see that it is positioned relative to the south east corner of a node (#1), defined by the argument given to the style, i.e. #2-wrap in the definition of \plate. #2 here is turn the first mandatory argument to the \plate command, i.e. the first one after the options. The node #2-wrap is a node defined with the fit option, and is a node that encompasses all the nodes given in the second mandatory argument of \plate.

The actual frame of the \plate is drawn by the third \node in its definition, which is a node that encompasses the caption and the list of nodes in the \plate (also via the fit library).

One way of moving the caption around is to redefine the plate caption style. As the library is written that has to be done before each \plate command with \tikzset. That is, add something like

\tikzset{plate caption/.append style={below right=0pt and 0pt of #1.north west}

before the \plate. Using append style as above you don't have to include the rest of the style definition, only the position will be overwritten. If you want to modify this for just one \plate, put a pair of braces around \tikzset and \plate, i.e.

{ % opening brace
\tikzset{..}
\plate{..}{..}{..}
} % closing brace

To late in the evening for me to try to modify everything, so in the code below I've only moved the C classes caption. Hopefully you can figure out the rest yourself.

\documentclass[border=3mm]{standalone} % For LaTeX2e
\usepackage{tikz}
\usetikzlibrary{bayesnet}

\begin{document}

\begin{tikzpicture}

  % Define nodes
  \node[obs]             (y)      {$y_{i}^{(j)}$};
  \node[obs, right=of y]  (f)      {$f_{ik}^{(j)}$};
  \factor[above=of y,yshift=0.7cm]   {yf}    {Cat} {} {} ; %
  \factor[above=of f,yshift=0.7cm]   {rf}    {Cat} {} {} ; 


  \node[latent, left=of yf]  (pi)      {$\pi_{c}^{(j)}$};
  \node[latent, above=of pi, yshift=0.5cm]  (beta)   {$\beta_{c}^{(j)}$};
  \factor[above=of pi, yshift=0.4cm] {pi-f} {left:Dir} {} {} ; %

  \node[latent, above=of yf, xshift=0.8cm, yshift=3cm ]  (t)   {$t_i$};
  \node[latent, above=of t, yshift=0.5cm]  (p)   {$p$};
  \node[latent, right=of p, xshift=0.8cm]  (alpha)   {$\alpha$};
  \factor[above=of t, yshift=0.5cm] {t-f} {left:Dir} {} {} ; %
  \factor[right=of p, xshift=0.5cm] {p-f} {Dir} {} {} ; %

  \node[latent, right=of rf]  (d)      {$z_{k,c}^{(i)}$};
  \node[latent, above=of d, yshift=0.5cm]  (gamma)   {$\gamma_{0,c}^{(i)}$};
  \factor[above=of d, yshift=0.4cm] {d-f} {right:Dir} {} {} ; %


  % Connect the nodes
  \factoredge {gamma}  {d-f}  {d} ;
  \factoredge {alpha}  {p-f}  {p}; %
  \factoredge {p}  {t-f}  {t}; %
  \factoredge {beta}  {pi-f}   {pi} ;
  \factoredge {pi}  {yf}   {y} ;
  \factoredge {d}  {rf}   {f} ;

 \gate {y-gate} {(yf)(yf-caption)} {t}
 \gate {f-gate} {(rf)(rf-caption)} {t}

% Plates
\plate [inner sep=0.3cm, xshift=0.1cm, yshift=-0.2cm,color=red] {pA} {(f)(rf)(d)(d-f)} {$k \in K_i$}; %
{\tikzset{plate caption/.append style={above=5pt of #1.north west}}
\plate [inner sep=0.3cm, xshift=0.2cm, color=blue] {pC} {(beta)(pi)(d)(gamma)} {C classes};}
\plate [inner sep=0.7cm, xshift=0.3cm, yshift=-0.4cm, color=brown] {pT} {(t)(gamma)(d)(yf)(y)(rf)(f)} {N objects};
\plate [inner sep=0.2cm, xshift=-0.2cm] {pM} {(beta)(pi)(yf)(y)(rf)(f)} {M workers} ;
\plate [inner sep=0.2cm, xshift=-0.05cm, yshift=0.15cm] {pJi} {(y)(f)} {$J_i$} 

%minimum height=1.5cm, minimum width=3.0cm, yshift=0.4cm,
\end{tikzpicture}
 \end{document}

enter image description here

  • 1
    Another option could be to add an empty caption in the \plate command, and make a new node relative to the plate node, e.g. \node [below right] at (pA.north west) {$k \in K_i$};. – Torbjørn T. Apr 6 '16 at 22:05
  • try kpsewhich on tikzmark too ;) – percusse Apr 6 '16 at 22:16
  • @Torbjørn T. Kudos for the clear and concise answer. I have tried your suggested approach, and it all worked seamlessly like magic. It was a great help!! – coffeeak Apr 7 '16 at 2:07
  • @percusse Had forgotten about tikzmark, but one difference is that texdoc tikzmark gives you a 'proper' manual, while texdoc bayesnet gives you only a short readme file. Still, 'undocumented' was perhaps a too strong word. – Torbjørn T. Apr 7 '16 at 7:16
0

I was playing around with the same repo and faced this issue. After a close inspection of the repo, I found that another solution is to simply include the plate label inside arguments for the new plate. This ensures that the captions are not superimposed.

Do something like this:

\plate {A} {(a)} {$M$} ;
\plate {B} {(b)(A)} {$N$} ;

Instead of :

\plate {A} {(a)} {$M$} ;
\plate {B} {(b)(a)} {$N$} ;
  • 2
    Welcome! Er ... what's the difference exactly? – cfr Aug 15 '18 at 2:14
  • @cfr, in the second row it is A instead of a. – Stefan Pinnow Aug 15 '18 at 4:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.