How to draw penrose diagrams with TikZ

The following code should get you started. Since I asume you are a tikz beginner, I'll provide some basic explanations after the code:

Code

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}

\begin{document}
\begin{tikzpicture}
\node (I)    at ( 4,0)   {I};
\node (II)   at (-4,0)   {II};
\node (III)  at (0, 2.5) {III};
\node (IV)   at (0,-2.5) {IV};

\path  % Four corners of left diamond
  (II) +(90:4)  coordinate[label=90:$i^+$]  (IItop)
       +(-90:4) coordinate[label=-90:$i^-$] (IIbot)
       +(0:4)   coordinate                  (IIright)
       +(180:4) coordinate[label=180:$i^0$] (IIleft)
       ;
\draw (IIleft) -- 
          node[midway, above left]    {$\cal{J}^+$}
          node[midway, below, sloped] {$\bar{u}=\infty$}
      (IItop) --
          node[midway, below, sloped] {$\bar{u}=0$}
      (IIright) -- 
          node[midway, below, sloped] {$\bar{u}=0$}
      (IIbot) --
          node[midway, above, sloped] {$\bar{v}=-\infty$}
          node[midway, below left]    {$\cal{J}^-$}    
      (IIleft) -- cycle;

\path % Four conners of the right diamond (no labels this time)
   (I) +(90:4)  coordinate (Itop)
       +(-90:4) coordinate (Ibot)
       +(180:4) coordinate (Ileft)
       +(0:4)   coordinate (Iright)
       ;
% No text this time in the next diagram
\draw  (Ileft) -- (Itop) -- (Iright) -- (Ibot) -- (Ileft) -- cycle;

% Squiggly lines
\draw[decorate,decoration=zigzag] (IItop) -- (Itop)
      node[midway, above, inner sep=2mm] {$r=0$};

\draw[decorate,decoration=zigzag] (IIbot) -- (Ibot)
      node[midway, below, inner sep=2mm] {$r=0$};

\end{tikzpicture}
\end{document}

Result

Result

Explanations

Tikz has a syntax very powerful and versatile. You can specify the coordinates of your drawing in different ways.

  • The first and more straighforward one is to use standard cartesian coordinates, such as (4,0). The default unit is cm.
  • You can also specify polar coordinates, for example (90:4). The first number is the angle, the second the radius (again in cm by default).
  • You can give a name to a coordinate, and use its name, as for example (I) or (II)
  • When building a path, you can specify the coordinates as absolute (all are measured wuth respect the origin which is at (0,0)) or relative (all are measured with respect to some given origin). For relative syntax precede the coordenate by +. For giving the origin, specify a first coordinate without the +.

With the above, you can read now the first few lines. Each of the initial \node commands define a named coordinate, with names (I), (II) and so on, at the given absolute cartesian coordinates (4,0), (-4,0) and so on). Also they place some text at those coordinates (the text between braces {I}, {II}, etc.)

The next \path command does a lot of things. It starts by setting the coordinate (II) as the origin for the remaining relative coordinates. Then, using polar coordinates relative to (II), some other named coordinates are defined, at right angles around (II) and distance 4 units. I named those coordinates (IItop), (IIbot) etc, using another syntax which uses the keyword coordinate as part of a path. At same time I typeset some labels a those coordinates, using the label option.

Once the four corners of the diamond are defined that way, they are joined with lines, and some labels are added above and below those lines. This is done in the next \draw command. The -- between two coordinates specifies that a line should be drawn. Before the final coordinate of each segment I use the node keyword to place text above and below those lines.

For the right diamond I removed all labels, and left only the drawing commands. Placing the labels should be almost identical to the first diamond and it's left as exercise.

Finally, the squiggly lines are added, connecting the appropiate coordinates at top and bottom of the diamond. I use again a node[midway] to place some text above (or below) those lines.

Hope this helps to get you started, or at least to motivate you to read the manual and give Tikz a try.

Update

The OP requested in a comment:

to draw a curved path from what you have called Ibot to the centre of the squigly line at the top of III labelled r=0. This could pass roughly 0.75 the way through the line that joins IIright and Itop.

This gives me the opportuniy of introducing other useful Tikz capability, which are calculated coordinates. In order to use this feature you need to add calc to the list of \usetikzlibrary arguments. In this case:

\usetikzlibrary{decorations.pathmorphing,calc}

Thanks to this library you can use at any place at which a coordinate is required, a mathematical expression (enclosed by $) involving addition or other operations with coordinates. It also defines a special operation called "interpolation", which has the following syntax: ($(A)!x!(B)$), where A and B are coordinates (cartesian, polar, named ones...) and x is a number between 0 and 1. The resulting coordinate is a point located in the line A-B, at a point proportional to x (0 means A, 1 means B). In fact, x can be negative or greater than 1, allowing extrapolation.

Using this feature, the pont "at the middle of the top squiggley line" would be: ($(IItop)!.5!(Itop)$), so the next command would draw a straight line connecting the two required points:

\draw[->]  % The -> adds an arrow tip
    (Ibot) -- ($(IItop)!.5!(Itop)$);

But the OP requested a curved line, not a straight one. To get a curved line, the easiest way (tikz also has several ways) is to replace -- by the to operator. This operator without options draws a straight line, the samen than --, but you can give options to it to bend the line.

For example, you can specify the angle at which the line leaves from Ibot, and the angle at which it should enter at the final point. This produces a curve. However, those parameters alone does not define a single curve, but a family of curves. You can fine-tune the curve obtained with the parameter looseness, which is 1 by default. Increasing this parameter makes the curve "more curve", and reducing it makes the curve more close to the original straight line.

By trial and error I've found these values:

\draw[->] 
    (Ibot) to[out=70, in=-15, looseness=1.5] ($(IItop)!.5!(Itop)$);

And the result is:

enter image description here


One possibility (as JLDiaz mentions in his comment) is to use coordinates to specify points, and then draw the lines joining the appropriate coordinates; the decorations library can be used to draw the zig-zag lines. A starting point (playing with my code and reading the TikZ documentation you can add the missing elements and customize the result):

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,decorations.pathmorphing}

\begin{document}

\begin{tikzpicture}[node distance=2cm]
% coordinates for the nodes
\coordinate (A) at (0,0);
\coordinate[above right = of A,label=$i^{\ast}$] (B);
\coordinate[right = 3cm of B,label=$i^{\ast}$] (C);
\coordinate[below right = of C] (D);
\coordinate[below right = of A] (E);
\coordinate[right = 3cm of E] (F);
% some straight lines uning the coordinates and adding labels 
\draw (A) -- node[above] {$f^{\ast}$} (B) -- node[below,sloped,pos=0.25] {$\bar{v}=0$} node[below,sloped,pos=0.75] {$H^{-}$}
(F) -- (D);
\draw (A) -- (E) -- (C) -- (D);
% some decorated lines uning the coordinates and adding labels 
\draw[decorate,decoration=zigzag] (B) -- node[above] {$r=0$} (C);
\draw[decorate,decoration=zigzag] (E) -- node[below] {$r=0$} (F);
\end{tikzpicture}

\end{document}

enter image description here


You have different possibilities. With some basic commands of tikz you can try this. I updated the first code . The final result is not complete but it's a good exercice to finish it by yourself.

Explanations

You have a lot of fine explanations in JLDIAZ's answer. I try to add some explanations to understand the difference between the codes.

Before drawing something, I like to know if I need to adapt the size of the picture with scale for example. I prefer to avoid the positioning library if I need a scaling picture.

\draw is a shorthand for \path[draw]. It's possible to define a path, to draw this path and to define, to draw at the same time some coordinates and nodes.

With the next code, I can use [scale=2] but It's also interesting to define some variables like \myunit(here 4 signifies 4 cm) with the \pgfmathsetmacro command.

Then it's impossible to draw with one path this sort of graphs. The first path begins with \draw (0,0) and it ends with cycle;.

When you add a new coordinate (relative or absolute) you can add to the path nodes. As you can see the code is very simple,but you need to know why sometimes you need to use coordinate or sometimes node. coordinate is a special node with some different parameters.

After --++(45:\myunit) I get a line between the origine (45:\myunit) is polar coordinates. Now I can add some nodes between the two points.

  • With coordinate (a)I named the last point
  • With node [above]{$i^+$} I placed a basic node above the last point
  • With node[pos=.5, above left] {$\cal{J}^+$} I placed a node above the middle of the line defined by the last points.

The last interesting possibility is used in the final path with

  • `\draw ... node[above=6pt] {$r=0$} node[below=1 cm] {III}``

It's possible to place the node where you want with something like [below=1 cm]

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}

\begin{document}

\begin{tikzpicture}%[scale=2]
\pgfmathsetmacro\myunit{4} 
 \draw     (0,0)            node [left] {$i^0$} 
       --++(45:\myunit)     coordinate (a)
                            node[pos=.5, above left]    {$\cal{J}^+$}
                            node[pos=.5, below, sloped] {$\bar{u}=\infty$}    
                            node [above]{$i^+$}
       --++(-45:2*\myunit)  node[pos=.25, below, sloped] {$\bar{u}=0$} 
                            coordinate (d)    
                            node [below]{$i^-$}
       --++(45:\myunit)     node [right]{$i^0$}
       --++(135:\myunit)    coordinate (b)    
                            node [above]{$i^+$}
       --++(-135:2*\myunit) coordinate (c)    
                            node [below]{$i^-$}
       --cycle;

 \draw [decorate, decoration=zigzag] (a) -- node[above=6pt] {$r=0$}
                                            node[below=1 cm] {III}
                                            (b) 

                                     (c) -- (d);

\end{tikzpicture}
\end{document} 

enter image description here

Tags:

Tikz Pgf