4

How do I draw a graph similar to this picture in LaTeX? The inequalities in the vertices are quite big in size, they're not small labels like A, B. I would like to have some expressions on the edges too, if it doesn't become too messy (not shown in the figure).

enter image description here

Note that there are 10 vertices on the left hand and over 20 on the right hand, not all of which are shown. There are multiple connections to and from nodes. So if there is an array-like way of specifying edges (e.g. draw each edge from edges = {(u1, v1), (u1, v2), (u2, v2), (u2, v3), (u3, v4)...}, then it would be better than specifying each edge manually in the figure.(e.g. draw edge (u1, v1), draw edge (u1, v2) etc.)

Also, I think I will need a bigger page size as well (I'm not going to print it, so arbitrarily large size is fine).

Preferably, I want something on the lines of: vertices list = (v1, v2, ...), edges list = ((u1, v1), (u2, v2), ...) and tikz/LaTeX to take care of the rest of the arrangement.

6
  • You can use TikZ.
    – Karlo
    Dec 11, 2015 at 16:14
  • 1
    @MWijnand I know. But I don't want to manually specify the position of 30 odd nodes. So I'm wondering if there's any elegant and automated way.
    – taninamdar
    Dec 11, 2015 at 16:18
  • TikZ provides several ways to reduce the drudgery of specifying lots of coordinates. What about using chains? Or picking some ideas from these examples
    – Thruston
    Dec 11, 2015 at 16:28
  • You might also find something useful in tikz berge
    – Thruston
    Dec 11, 2015 at 16:32
  • @Thruston Can you elaborate -- "TikZ provides several ways to reduce the drudgery of specifying lots of coordinates." I looked into berge, but the graph which I want to draw isn't exactly complete or any other special kind of graph.
    – taninamdar
    Dec 11, 2015 at 17:03

2 Answers 2

2

I approached the problem using TikZ and the shapes library, though I think the ellipses are not so nice for such long content. There are two chains, both going downwards (below), all nodes have a fixed height (minimum height= and ìnner ysep=) such that they are aligned by using the same stepnode distance` on both chains,

\documentclass{standalone}
\usepackage{tikz} \usetikzlibrary{chains,positioning,scopes,shapes}
\begin{document}
    \tikzstyle{myNode}=[on chain, align=center,shape=ellipse,draw, minimum width=3cm, minimum height=1cm,inner ysep=0pt]
    \begin{tikzpicture}
        \begin{scope}[start chain=going below, node distance=2cm]
            \node [on chain, myNode] (L1) at (0,-3) {\(x_1\quad x_2\)\\\(v_2\geq0\)};
            \node [on chain, myNode] (L2) {\(x_1\quad (1-x_2)\)\\\((k-1)v_2 - (k+1)v_3 \geq 0\)};   
            \node [on chain, myNode] (L3) {\(1-x_1\quad (1-x_2)\)\\\((k+1)v_1 - (2k-1)v_2 \geq 1\)};
        \end{scope}
        \begin{scope}[start chain=going below, node distance=2cm]
            \node [on chain, myNode] (K1) at (7,0) {\(x_1\quad x_2\quad x_3\)\\\(2v_2\geq0\)};
            \node [on chain, myNode] (K2) {\(x_1\quad x_2 \quad (1-x_3)\)\\\(v_2 + (k-2)v_3\geq 0 \geq 0\)};    
            \node [on chain, myNode] (K3) {\(x_1(1-x_2)(1-x_3)\)\\\((k-1)v_2 - (2k-2)v_3\geq 0\)};
            \node [on chain, myNode] (K4) {\(x_1(1-x_b)(1-x_c)\)\\\(\cdots\)};
            \end{scope}
        \draw[->] (L1) -- (K1);
        \draw[->] (L1) -- (K2);
        %
        \draw[->] (L2) -- (K2);
        \draw[->] (L2) -- (K3);
        %
        \draw[->] (L3) -- (K4);
    \end{tikzpicture}
\end{document}

Note that the first (left) chain starts exactely one height earlier (1cm height and 2cm node distance).

The result still needs some styling (and maybe other shapes than ellipse but its a starting point.

ellipses

Edit/Update In the first case, all edges start at the center point, because the \draw always the start/end point to be the center. to change that one can use the meta coordinates of the nodes (.north,.east,.south and .west), i.e. using for the drawing of the edges

        \draw[->] (L1.east) -- (K1.west);
        \draw[->] (L1.east) -- (K2.west);
        %
        \draw[->] (L2.east) -- (K2.west);
        \draw[->] (L2.east) -- (K3.west);
        %
        \draw[->] (L3.east) -- (K4.west);

to obtain (includes removing the shape=ellipse and hence having rectangles):

rectangles

6
  • That looks great. I'm not particular about using ellipses, anything else would work just as good. What would you suggest?
    – taninamdar
    Dec 11, 2015 at 17:43
  • Also, is there any way to make the starting point of edges same? (I.e. all edges starting from a node start from single point)
    – taninamdar
    Dec 11, 2015 at 17:44
  • If you just remove shape=ellipse you get rectangles, which would be much nicer I think.
    – Ronny
    Dec 11, 2015 at 17:44
  • I don't understand your starting point request, can you explain a little more?
    – Ronny
    Dec 11, 2015 at 17:45
  • Edge L1 K1 starts at the top of L1, whereas L1 K2 starts at the left end. Would it be possible that both start at the left (or any single point on the boundary, for that matter)
    – taninamdar
    Dec 11, 2015 at 17:47
2

Here's an approach in Metapost for comparison, using some elongated super-ellipses.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

% a little TeX alignment for each "node"
verbatimtex
\def\m#1{$\vcenter{\let\\\cr\halign{\hfil$##$\hfil\cr#1\crcr}}$}
etex

beginfig(1);

% "se" is a shape to surround each text block
path se; se = (superellipse(3 right, up, 3 left, down, 0.89)) scaled 23;

% define the source and target equations
picture source[], target[];

source1 = btex \m{x_1 x_2\\v_2\ge0} etex;
source2 = btex \m{x_1(1-x_2)\\(k-1)v_2-(k+1)v_3\ge0} etex;
source3 = btex \m{(1-x_1)(1-x_2)\\(k+1)v_1-(2k-1)v_2\ge1} etex;

target1 = btex \m{x_1 x_2 x_3\\2v_3\ge0} etex;
target2 = btex \m{x_1 x_2 (1-x_3)\\v_2+(k-2)v_3\ge0} etex;
target3 = btex \m{x_1 (1-x_2) (1-x_3)\\(k-1)v_2-(2k-2)v_3\ge0} etex;
target4 = btex \m{x_1 (1-x_b) (1-x_c)\\\dots} etex;

% u = horizontal separation, v = vertical
u = 120; v = 64;

% redefine each node with background, edge, and position; and then draw it
for i=1 upto 3:
  source[i] := image(fill se withcolor .9[blue,white]; draw se; label(source[i], origin)) shifted (-u,v*(3-i));
  draw source[i];
endfor
for i=1 upto 4:
  target[i] := image(fill se withcolor .9[red,white]; draw se; label(target[i], origin)) shifted (+u,v*(3.5-i));
  draw target[i];
endfor

% a macro to do the connnections, with neat line crossings
vardef connect(expr i,j) = 
  save A; path A;
  A = center source[i] shifted 24 right -- 
      center target[j] shifted 24 left
      cutbefore se shifted center source[i]
      cutafter  se shifted center target[j];
  undraw subpath (0.2,0.8) of A withpen pencircle scaled 3; 
  drawarrow A;
  enddef;

% one loop of each source "node"
forsuffixes $=1,2:   connect(1,$); endfor
forsuffixes $=2,3,4: connect(2,$); endfor
forsuffixes $=3,4:   connect(3,$); endfor

endfig;
end.
1
  • +1: I like the "programming language" style approach of Metapost, it's very easy to understand. If only tikz were this systematic... (I'm still struggling to convert Ronny's answer into a systematically drawn figure using foreach)
    – taninamdar
    Dec 11, 2015 at 19:46

You must log in to answer this question.

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