5

I'm writing a paper about modal logic in which I'll quite often need to draw a diagram of 'worlds'. Every world is represented by a dot, which has two labels: the name of the world on one side of the dot and some propositional formulas on the other side. Arrows connect different worlds and some worlds may be connected to themselves.

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

\begin{document}
  \begin{tikzpicture}[scale=2]
    \coordinate (1) at (0,0);
    \coordinate (2) at (1,0);
    \coordinate (3) at (-60:1);
    \foreach\x in {1,2,3}{
      \node[fill,circle,inner sep=1pt, label=left:$w_\x$] (world\x) at (\x) {};
    }
    \node[right] at (1) {$\neg p, q$};
    \node[right] at (2) {$p, q$};
    \node[right] at (3) {$p, q$};
    \draw[->] (world2) to (world3);
    \draw[->] (world3) to (world1);
    \draw[->,min distance=10,in=60,out=120] (world2) to (world2);
  \end{tikzpicture}
\end{document}

Diagram

As a TikZ-newbie, I don't think my first attempt is very bad, but it can surely be improved. For example, I think the labels are too close to the arrows and there should be a small 'gap' between the dots and the startpoint/endpoint of the arrows.

Are there some tricks to solve the shortcomings of my diagram? Is the set-up of my code good enough to be used for future, similar diagrams?

1 Answer 1

2

There actually is a gap between worlds and arrows already because, I think, you are filling but not drawing the nodes and so the line width is still there, but not filled. If you don't want the gap, this is easily remedied by adding draw to the nodes.

If, on the other hand, you want a larger gap, then you can use shorten > and/or shorten < for the picture (or particular arrows, but presumably you want consistency here).

For example, we could try

\begin{tikzpicture}[scale=2, shorten >=.5pt, shorten <=.5pt]

to add .5pt distance between the worlds and each end of the arrows.

For the label distances, I would be inclined to create all the labels as labels and then to control their distance globally using label distance for the picture. This way, you ensure consistency and flexibility as it is easy to change if required.

To do this, we could create the nodes and labels in one step using two variables in the loop: one for the position and one for the label. We can keep count of the worlds using count and use this to create the standard world label.

For example:

  \foreach \x/\j [count=\xno] in {(0,0)/{$\lnot p, q$},(1,0)/{$p, q$},(-60:1)/{$p, q$}}{
    \node [fill, circle, inner sep=1pt, label=left:$w_\xno$, label=right:\j] (world\xno) at \x {};
  };

Here, \x is the position ((0,0) for the first world) and \j is the set of wffs ($\lnot p, q$ for the first world). \xno keeps count of the worlds (1 for the first world). Then the \node... command creates the world, names it appropriately (world1 for the first world) and puts the world's name on the left ($w_1$ for the first world) and the set of wffs on the right ($\lnot p, q$).

We can set the distance of the labels from the worlds by modifying the configuration of the tikzpicture:

\begin{tikzpicture}[scale=2, label distance=2pt, shorten >=.5pt, shorten <=.5pt]

or we could do this for a particular part of the picture by using a scope if required

\begin{scope}[label distance=5pt]
   ...
\end{scope}

Then the result looks like this:

better worlds

Complete code:

\documentclass[tikz,multi,border=10pt]{standalone}
\begin{document}
\begin{tikzpicture}[scale=2, label distance=2pt, shorten >=.5pt, shorten <=.5pt]
  \foreach \x/\j [count=\xno] in {(0,0)/{$\lnot p, q$},(1,0)/{$p, q$},(-60:1)/{$p, q$}}{
    \node [fill, circle, inner sep=1pt, label=left:$w_\xno$, label=right:\j] (world\xno) at \x {};
  };
  \draw [->] (world2) to (world3);
  \draw [->] (world3) to (world1);
  \draw [->, min distance=10,in=60,out=120] (world2) to (world2);
\end{tikzpicture}
\end{document}
6
  • Thank you! (+1) I love your solution for working with just 1 loop and the labels look prettier too. Just one more thing: I actually meant that I'd like to have a small gap (say, 1pt) between the worlds and the arrows' starting/ending points. I think the diagram may be a bit clearer when the arrows and worlds don't stick together. Of course, feel free to advice otherwise.
    – Jeroen
    Mar 21, 2016 at 13:46
  • I actually get a gap if I don't use draw for the \node. Do you want a larger gap?
    – cfr
    Mar 21, 2016 at 13:59
  • Ow, it's very small, but you are right, I see it now as well. Yes, I'd like to see the effect of a larger gap.
    – Jeroen
    Mar 21, 2016 at 14:01
  • Please see edit. I misread your question before - sorry. I think I saw the gap and so, since there was one, must have jumped to the conclusion that you didn't want it. I've used .5pt in the example, but you can increase this, obviously, for a larger gap.
    – cfr
    Mar 21, 2016 at 14:07
  • Absolutely perfect! Don't worry, beginners often have the gift to confuse the experts... :-)
    – Jeroen
    Mar 21, 2016 at 14:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .