Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I need to represent graphs like the one below using xypics. They arise as the Hasse diagram of the Green order of finite semigroups (specifically finite Left Regular Bands) with the homomorphism to its support lattice. I know the very basics on how to draw lines and place points, but I don't know how one would draw ovaloids around a mass of points like in the image below. Also, I'd rather them not being ellipses.

Thank you for your time!

Screen shot

share|improve this question
1  
Would you be okay with tikz instead? –  Tom Bombadil May 16 '13 at 11:33
    
@TomBombadil I would be okay with any solution. I don't know how dissimilar tikz and xy-pic are, but I'll adopt the one most suited for my purpose. –  Olivier Bégassat May 16 '13 at 11:35
    
@AlainMatthes I have very limited experience with xy-pic, and none with tikz, so no special allegiance to either. –  Olivier Bégassat May 16 '13 at 11:38
    
@OlivierBégassat There is tikz-cd. –  Qrrbrbirlbel May 16 '13 at 15:56

6 Answers 6

up vote 6 down vote accepted

It's possible to use ellipse but it's better to use a rectangle with rounded corners and fit.

 \documentclass[11pt]{scrartcl}
 \usepackage{tikz}
 \usetikzlibrary{fit}

 \begin{document}
 \begin{tikzpicture}[y=1.5cm,
       every fit/.style={inner sep=4mm,orange,dashed,rounded corners=4mm,draw,line width=0.6mm}]

 \path (3,8)   coordinate  (s0)
       (1,6)   coordinate  (s1)  (5,6) coordinate (s2)
       (1,4)   coordinate  (s3)  (3,4) coordinate (s4)   (5,4) coordinate (s5)
       (0,2)   coordinate  (s6)  (1,2) coordinate (s7)   (2,2) coordinate (s8) (3,1.5) coordinate (s9) 
       (4,2.5) coordinate (s10)  (6,2) coordinate (s11);

  \node[fit=(s0)] (f1){}; \node[fit=(s1)(s2)](f2){}; \node[fit=(s3)(s5)](f3){};     
  \node[fit=(s6)(s9)(s10)(s11)](f4){};
  \node[right] at (f1.east) {$A$};   \node[right] at (f2.east) {$B$}; \node[right] at (f3.east) {$C$};
  \node[right] at (f4.east) {$D$};
  \draw[thick] (s0) -- (s1) -- (s3) -- (s6)
               (s1) -- (s4) -- (s7) (s4) -- (s8) (s4) -- (s9)
               (s0) -- (s2) -- (s5) -- (s11)  
               (s5) -- (s10);
  \draw[thick,double=black,draw=white]  (s2) -- (s3) (s2) to[out=-100 ,in=10] (s6);
  \foreach \i in {0,...,11} \draw[fill=blue!40]  (s\i) circle (2pt);
  \draw[->] (6,5) -- node [above]{$\theta$} (8,5);
  \path (9,8) coordinate   (t0)
        (9,6) coordinate   (t1)  
        (9,4) coordinate   (t2) 
        (9,2) coordinate   (t3) ;
   \draw[thick] (t0) -- (t1) -- (t2) -- (t3);
   \foreach \i in {0,...,3} \draw[fill=red!40]  (t\i) circle (2pt);
 \end{tikzpicture}
 \end{document}

enter image description here

share|improve this answer
    
This is absolutely beautiful! –  Olivier Bégassat May 16 '13 at 20:28
    
This is truly a great answer. Thank you very much! –  Olivier Bégassat May 16 '13 at 20:47
    
Thanks but it's possible to use other methods with tikz to add the nodes without the coordinates. This solution uses basic tools of tikz. –  Alain Matthes May 16 '13 at 21:05

Using xy-pic as tagged by you.

Code:

\documentclass[border=8]{standalone}
\usepackage[all]{xy}
\begin{document}
\xymatrix{
&&&  *=0{\xy(-3,-4);(5,4) **\frm<44pt>{.}\endxy \bullet}  \ar@{-}[dl] \ar@{-}[dr]  & \ar@{}[l]_{A}  &&&&*=0{\bullet} \ar@{-}[d] \\
&& *=0{\xy(-2,-2);(24,2) **\frm<44pt>{.}\endxy \bullet} \ar@{-}[dr] |!{[d];[rr]}\hole \ar@{-}[d] 
&& *=0{\bullet} \ar@/^1.7pc/@{}[dddlll] \ar@{-}[dll] & \ar@{}[l]_{B} &&&*=0{\bullet} \ar@{-}[d] \\
&& *=0{\xy(-2,-2);(24,2) **\frm<44pt>{.}\endxy \bullet} \ar@{-}[ddl] & *=0{\bullet} \ar@{-}[ddl] |!{[dd];[lll]}\hole \ar@{-}[dd] |\hole  \ar@{-}[ddr] |!{[dd];[uur]}\hole & *=0{\bullet} \ar@{-}[ddr] \ar@{-}[ddrr] & \ar@{}[l]_{C} & \ar@(r,l)[r]_{\theta} &&*=0{\bullet}\ar@{-}[dd]\\
& *=0{}\\
& *=0{\xy(-2,-2);(56,2) **\frm<44pt>{.}\endxy  \bullet} & *=0{\bullet} & *=0{\bullet} & *=0{\bullet} & *=0{\bullet} & *=0{\bullet} & \ar@{}[l]_>>>>>{D} &*=0{\bullet}\\
} 
\end{document}

Output:

certain graphs

share|improve this answer
    
Thank you very much : ) –  Olivier Bégassat May 17 '13 at 15:27
    
@OlivierBégassat if possible can you tell me what category do these "certain graphs" belong to ? My idea was to make the title of Q little more informative and easy for googlers and track back via tex.sx search. You can update the title to make for eg: "Representing automata or commutative diagrams ". Forgive my ignorance on this graphs topic –  texenthusiast May 17 '13 at 15:33
1  
This answer deserves way more votes, as it is the only one actually using xy-pic. –  Henri Menke May 17 '13 at 15:34
    
@HenriMenke more worried with no of upvotes to Q –  texenthusiast May 17 '13 at 15:40
1  
@texenthusiast My goal is to use this to represent the Hasse diagram of the Green order on a finite Left Regular Band (LRB) together with the map to its ideal lattice. –  Olivier Bégassat May 17 '13 at 15:41

enter image description here

Asymptote uses very natural approach to build this kind of graphs, see code below. This graph is constructed with more-or-less manual positioning tweaks, but it can be more automated if necessary. gr.tex:

\documentclass[10pt,a4paper]{article}
\usepackage[english]{babel}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{lmodern}
\usepackage{graphicx}
\usepackage[inline]{asymptote}

\begin{document}

\begin{figure}
\begin{asy}
unitsize(12mm);
pair d=(1,1.3); // next level offset
pair dout=(0.2,0.2);  // offset for the outline

pair[] A={(0,0)};

pair[] B={
(-d.x,-d.y),(d.x,-d.y)
};

pair[] C={
(-d.x,-2d.y),(0,-2d.y),(d.x,-2d.y)
};

pair[] D={
(-1.5d.x,-3d.y),
(   -d.x,-3d.y),
(-0.4d.x,-3d.y),
(      0,-3d.y-0.2d.y),
( 0.2d.x,-3d.y+0.2d.y),
( 1.2d.x,-3d.y),
};

real qx=2.5d.x;
pair[] q={
  (qx,A[0].y),
  (qx,B[0].y),
  (qx,C[0].y),
  (qx,D[0].y),  
};

pen dashed=linetype(new real[] {4,3}); // set up dashed pattern

real pw=0.8pt;
real gapw=3pw;

pen lpen=darkblue+pw;
pen dpen=orange+dashed+pw;

void Dot(pair v, pen p=currentpen){
  dot(v,p,UnFill);
}

void Dots(pair[] P){
  for(int i=0;i<P.length;++i){
    Dot(P[i]);
  }
}

void outline(pair[] v,pair dout=(0.2,0.2), string s="",pen p=dpen){
  pair l=v[0], r=v[v.length-1];
  pair c=0.5(l+r);

  guide g=
    (r+(dout.x,0))
    ..(r+(0,dout.y))
    --(l+(0,dout.y))
    ..(l+(-dout.x,0))
    ..(l+(0,-dout.y))
    --(r+(0,-dout.y))
    ..cycle
    ;
  draw(g,p); 
  label(s,r+dout,NE);
}

outline(A,"$A$");
outline(B,"$B$");
outline(C,"$C$");
outline(D,dout=(0.2,0.5),"$D$");

draw(B[0]--A[0]--B[1],lpen);
draw(C[0]--B[0]--C[1],lpen);

draw(C[0]--B[1],white+gapw);
draw(C[0]--B[1]--C[2],lpen);

draw(C[0]--D[0],lpen);

draw(C[1]--D[1],lpen);
draw(C[1]--D[2],lpen);
draw(C[1]--D[3],lpen);

draw(C[2]--D[4],lpen);
draw(C[2]--D[5],lpen);

guide g=B[1]..0.5(C[1]+C[2])..D[0];

draw(subpath(g,1,2),white+gapw);
draw(g,lpen);

draw(q[0]--q[1]--q[2]--q[3],lpen);

for(int i=0;i<q.length;++i){
  fill(circle(q[i],0.1),white);
}

Dots(A);Dots(B);Dots(C);Dots(D);Dots(q);

pair rarrowCenter=0.5(B[0]+C[0])+(3d.x,0);

label("$\theta \atop \longrightarrow$",rarrowCenter);

\end{asy}
%
\hsize8cm
\caption{Graph}
\end{figure}

\end{document}

To process it with latexmk, create file latexmkrc:

sub asy {return system("asy '$_[0]'");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");

and run latexmk -pdf gr.tex.

Or you can save the content between \begin{asy} \end{asy} in, say, g.asy file, run asy -f pdf g.asy and get a standalone g.pdf, which can be included as a graphic file.

share|improve this answer
    
Thank you so much, this is exactly what I needed! –  Olivier Bégassat May 16 '13 at 14:57
    
How could I make the gap larger between the two graphs, for instance adding 2 cm? Also, how would you make the letters A,B,C,D smaller? –  Olivier Bégassat May 16 '13 at 15:03
    
+1 but, are all of these packages necessary? –  cmhughes May 16 '13 at 15:49
    
@Olivier Bégassat: You can use for example "$\scriptstyle A$" instead of "$A$" to make the letters smaller. In this example pair d=(1,1.3); // next level offset is used to control the distance between nodes (its x-part d.x=1) and levels (its y-part d.y=1.3). To increase the distance between sub-graphs, just increase y-part of d, for example d=(1,1.3+1);` or d=d+(0,1);. Play with unitsize(); to get the results you want. –  g.kov May 16 '13 at 15:56
    
@cmhughes:You are right, for this particular MWE just \usepackage[inline]{asymptote} is enough. –  g.kov May 16 '13 at 16:01

With TikZ, this can be done quite easily using the fit library. First, define nodes for all points that you want to fit (if you know your points in advance, then those forming the convex hull would be enough). Then you can make a new node using [fit=(node 1)(node 2)...(node n)]. To check that it works I did this 100 times for ten random points, as you can see the size of the output varies accordingly

Code

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{fit}

\begin{document}
\foreach \y in {1,...,100}
{   \pgfmathsetseed{\y*101}
    \begin{tikzpicture}
        \foreach \x in {1,...,10}
        {   \node[fill=black,circle] (x\x) at (rnd*4-2,rnd*4-2) {};
        }
        \node[fit=(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10),circle,draw,dashed,inner sep=0pt] {};
    \end{tikzpicture}
}

\end{document}

enter image description here

share|improve this answer
    
Can you do this with an ovaloid shape? Also, are the points you placed points from which arrows can emanate and be directed toward? –  Olivier Bégassat May 16 '13 at 12:23
    
Page 189 of the TikZ & pgf manual shows you how to do it. It should give the desired result if you just replace circle in the last node of Toms example with ellipse (this might only work for newer versions of TikZ). –  Habi May 16 '13 at 14:55

Here's my try at a very basic example in TikZ. My installation of Tikz doesn't know the ellipse key for the fitting, but as said above, recent installations should know it.

\documentclass{article}
\usepackage{tikz}
    \usetikzlibrary{fit}
\usepackage[active,tightpage]{preview}
    \PreviewEnvironment{tikzpicture}

\begin{document}

\begin{tikzpicture}

\node at (0,0) (a) {o};

\node at (-0.5,-1) (b1) {o};
\node at (0.5,-1) (b2) {o};
\draw [->] (a) -- (b1);
\draw [->] (a) -- (b2);

\node at (-0.75,-2) (c1) {o};
\node at (0,-2) (c2) {o};
\node at (0.75,-2) (c3) {o};
\draw [->] (b1) -- (c1);
\draw [->] (b1) -- (c2);
\draw [->] (b2) -- (c1);
\draw [->] (b2) -- (c3);

\node at (-1,-3) (d1) {o};
\node at (-0.5,-3) (d2) {o};
\node at (0,-3) (d3) {o};
\node at (0.25,-2.75) (d4) {o};
\node at (0.5,-3.25) (d5) {o};
\node at (1,-3) (d6) {o};
\draw [->] (c1) -- (d1);
\draw [->] (b2) to[out=-120,in=60] (d1);
\draw [->] (c2) -- (d2);
\draw [->] (c2) -- (d3);
\draw [->] (c2) -- (d4);
\draw [->] (c3) -- (d5);
\draw [->] (c3) -- (d6);

\node [draw=red,fit=(a),label=0:A] {};
\node [draw=blue,fit=(b1) (b2),label=0:B] {};
\node [draw=green,fit=(c1) (c2) (c3),label=0:C] (C) {};
\node [draw=cyan,fit=(d1) (d2) (d3) (d4) (d5) (d6),label=0:D] (D) {};

\node at (3,0) (e) {o};
\node at (3,-1) (f) {o};
\node at (3,-2) (g) {o};
\node at (3,-3) (h) {o};
\draw [->] (e) -- (f);
\draw [->] (f) -- (g);
\draw [->] (g) -- (h);

\draw [->] (2,-2) -- (2.5,-2) node [midway,above] {\(\theta\)};

\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer

With the tikz-cd package, a few adjustment and minor improvements one could do the following.

There are a few comments in the code.

You can use the backgrounds library and use

insert after arrows={
  \begin{scope}[on background layer]
     <everything inside here will be drawn behind everything else>
  \end{scope}
}

if you want to have something behind everything else. This is used for the C cloud to show how crossing over works.

There are advanced ways around this, of course.

Code

\documentclass[tikz,convert]{standalone}
\usepackage{tikz-cd}
\usetikzlibrary{decorations,fit,backgrounds}
\newcommand*{\tikzcdset}{\pgfqkeys{/tikz/commutative diagrams}}
\tikzset{cd/.code={\tikzcdset{#1}}}
\makeatletter
\tikzcdset{% Insert arbitrary code after and before the arrow get drawn
  insert before arrows/.style={/tikz/commutative diagrams/matrix of math nodes maybe/.append code={
    \expandafter\def\expandafter\tikzcd@savedpaths\expandafter{\tikzcd@savedpaths#1}}},
  insert after arrows/.style={/tikz/execute at end picture={#1}}}
\makeatother
\tikzcdset{
  % What now follows are a few quick fixes to the 'crossing over' style.
  % The actual line is now a decoration that doesn't start right at the border of the nodes as this would over-draw other lines.
  % Of course we could just draw the crossing lines first and then every other line but that means more work.
  % 'coc' stands for 'corssing over clearance'
  %% The following style set only the factor to the 'crossing over clearance' value
  coc </.initial=3,coc >/.initial=3,coc/.style={coc <={#1},coc >={#1}},no coc/.style={coc >=0,coc <=0},
  crossing over/.style={% re-definition, you can add arbitrary styles with 'crossing over=<styles>'
    /tikz/preaction={
      /tikz/draw=\pgfkeysvalueof{/tikz/commutative diagrams/background color},
      /tikz/arrows=-,
      /tikz/line width=\pgfkeysvalueof{/tikz/commutative diagrams/crossing over clearance},
      /tikz/decoration={
        name=curveto,pre=moveto,post=moveto,
        pre length=\pgfkeysvalueof{/tikz/commutative diagrams/coc <}*\pgfkeysvalueof{/tikz/commutative diagrams/crossing over clearance},
        post length=\pgfkeysvalueof{/tikz/commutative diagrams/coc >}*\pgfkeysvalueof{/tikz/commutative diagrams/crossing over clearance}},
      /tikz/decorate,#1}},%
  name/.style={% I want to give a name to the inner matrix
    /tikz/every matrix/.append style={name={#1}}}}
\tikzcdset{% the 'dotted diagram' style activates the styles and what not for the diagram that doesn't use any contents in the
  dotted diagram/.style={
    cd={
      diagrams={
        crossing over clearance=+2pt, % the crossing-over area was to big for my taste
        arrows={/tikz/arrows=-},      % I don't want no arrows nowhere
        cells={                       % It's a matrix.
          nodes={
            shape=circle,
            inner sep=+0pt,
            outer sep=+0pt,
            minimum size=+1.5pt,
            fill}}}}}}
\tikzset{% now the dotted line is a node (the shape is not specified here)
  cloud/.style args={#1:#2}{
    draw,
    dashed,
    fit={#1},
    label={north east:{#2}}}}
\begin{document}
\tikzset{/tikz/commutative diagrams/dotted diagram}
\begin{tikzcd}[
  row sep=1cm,
  column sep=.5cm,
  name=m, % for the nodes, is needed in the to fitted nodes
  insert after arrows={% this stuff is drawn after the arrows and thus over-draw/fill these
    \node[circle,cloud=(m-1-4):$A$]{};
    \node[rounded corners,cloud=(m-2-3)(m-2-5):$B$]{};
    \begin{scope}[on background layer]
      \node[rounded corners,cloud=(m-3-3)(m-3-5):$C$,fill=red!20]{};
    \end{scope}
  },
  insert before arrows={% this is drawn before all arrows, you can see this very good where the bended line crosses one arrow and the border of the D cloud
    \node[rounded corners,cloud=(m-4-4)(m-5-1)(m-5-6)(m-6-4):$D$]{};}
  ]
 % Let's start.
 % The A cloud
    &    &    & {} \dlar \drar \\
 % The B cloud
    &    & {} \dar \drar 
              &    & {}  \arrow[crossing over]{dll} \dar 
              \\
 % The C cloud
    &    & {} \arrow{ddll}
              & {} \arrow{ddll} \arrow{ddl} \dar
                   & {} \arrow{dddl} \arrow{ddr}
                         \\
 % The D cloud
    &    &    & {} &    &    \\[-.8cm]
 {} \arrow[bend right, crossing over]{uuurrrr} \arrow{uurr}
    & {} & {} &    &    & {} \\[-.8cm]
    &    &    & {}
\end{tikzcd}
\end{document}

Output

enter image description here

share|improve this answer
    
Thank you! I might end up using this actually, as I can't get ASYMPTOTE to work. –  Olivier Bégassat May 16 '13 at 18:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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