6

I'm drawing a tikzpicture and trying to make it flexible. There is a group of symbols that I want to be able to move around while maintaining their relative positions. So far I've tried concatenating commands inside one \draw' and using+(x,y)' coordinates to keep things relative. In the following diagram I want to be able to move what's inside the circle around as a group.

MWE Output

I've made some progress but a side effect of the way I've done it is that I can't get this thing to include arrows on the ends of the lines between my S nodes. If I type `->' instead of '--' for example, it just ignores it. I'm drowning in the manual as usual. Perhaps there is a better approach altogether that I'm missing. Any tips that might help?

MWE

\documentclass[border=6mm]{standalone}

\usepackage{tikz}

\begin{document}
%
\begin{tikzpicture}[>=latex]
    \draw (1.5,1.5) circle (1.5cm);
    \draw (0.5,1.8) node {$S_1$}
        +(2,0) node {$S_2$} 
        +(1,-1) node {$S_3$}
        +(0.4,0) -- +(1.6,0)
        +(1.8,-0.20) -- +(1.2,-0.8)
        +(0.2,-0.2) -- +(0.8,-0.8);
\end{tikzpicture}
%
\end{document}

Another type of element that I can't figure out how to get arrows on inside a group is an arc. This is shown in the following picture. I know how to do this with the arcs as separate elements but I can't make it work inside the group.

enter image description here

Extra MWE

\documentclass[border=6mm]{standalone}

\usepackage{tikz}

\begin{document}
%
\begin{tikzpicture}[>=latex]
    \draw (1.5,1.5) circle (2.0cm);
    \draw (0.5,1.8) node {$S_1$}
        +(2,0) node {$S_2$}
        +(1,-1) node {$S_3$}
        +(0.4,0) edge[<->] +(1.6,0)
        +(1.8,-0.20) edge[<->] +(1.2,-0.8)
        +(0.2,-0.2) edge[<->] +(0.8,-0.8);
    \draw[<->] (0.5,2.05) arc (0:270:0.3cm);
    \draw[<->] (2.8,1.75) arc (-90:180:0.3cm);
    \draw[<->] (1.3,0.65) arc (-225:45:0.3cm);
\end{tikzpicture}
%
\end{document}

3 Answers 3

8

You can use edge[->] instead of --.

\documentclass[border=6mm]{standalone}

\usepackage{tikz}

\begin{document}
%
\begin{tikzpicture}[>=latex]
    \draw (1.5,1.5) circle (1.5cm);
    \draw (0.5,1.8) node {$S_1$}
        +(2,0) node {$S_2$}
        +(1,-1) node {$S_3$}
        +(0.4,0) edge[->] +(1.6,0)
        +(1.8,-0.20) edge[->] +(1.2,-0.8)
        +(0.2,-0.2) edge[->] +(0.8,-0.8);
\end{tikzpicture}
%
\end{document}

enter image description here

For the edit, not exactly an arc with specified dimensions but this should serve as the starting point.

\documentclass[border=6mm]{standalone}

\usepackage{tikz}

\begin{document}
%
\begin{tikzpicture}[>=latex]
\draw (0,0) coordinate (-center) circle (1.5cm);
    \draw (150:0.75) node (-s1) {$S_1$}
            (30:.75) node (-s2) {$S_2$}
             (-90:.75) node (-s3) {$S_3$}
             (-s1.center) edge[->,shorten >=3mm, shorten <=3mm] (-s2.center)
             (-s1.center) edge[->,shorten >=3mm, shorten <=3mm] (-s3.center)
             (-s2.center) edge[->,shorten >=3mm, shorten <=3mm] (-s3.center)
             (-s1.north) edge[->,bend right,distance=0.5cm,in=-45,out=-140](-s1.west)
             (-s2.north) edge[->,bend right,distance=0.5cm,in=45,out=140,looseness=5] (-s2.east)
             (-s3.east) edge[->,bend right,distance=0.8cm,in=40,out=140] (-s3.west);
\end{tikzpicture}

\end{document}

enter image description here

4
  • I now need to make the circle a little bigger and have 3 240° 0.4cm radius arcs with arrows on each end pointing to each of the states included in my group. I can do the arcs, but how do I get the arrows? The edge[<->] construct doesn't seem to work with an arc. Apr 10, 2014 at 11:29
  • @GeoffPointer You can use bend left and bend right with suitable distance. Bend left=2cm for example. I didn't understand the final requirement though.
    – user11232
    Apr 10, 2014 at 13:43
  • I've added a picture to clarify what I mean with a new MWE. Apr 10, 2014 at 14:45
  • Your addition is very helpful. Not just the bends, but using the centre of the circle, polar coordinates, the shorten idea and so on. Thank you. Apr 12, 2014 at 5:46
11

Harish already solved the problem with arrows, but if you want to move around a group of symbols I'd suggest to use a pic (new with TiKZ 3.0).

\documentclass[border=6mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
%

\tikzset{
    mygroup/.pic={
    \draw (0,0) coordinate (-center) circle (1.5cm);
    \draw (150:0.75) node (-s1) {$S_1$}
            (30:.75) node (-s2) {$S_2$}
             (-90:.75) node (-s3) {$S_3$}
             (-s1.center) edge[->,shorten >=3mm, shorten <=3mm] (-s2.center)
             (-s1.center) edge[->,shorten >=3mm, shorten <=3mm] (-s3.center)
             (-s2.center) edge[->,shorten >=3mm, shorten <=3mm] (-s3.center);
    }
}
\begin{tikzpicture}[>=latex]
    \pic (A) {mygroup};
   \pic[rotate=15,transform shape] at (3,2) (B) {mygroup};
   \pic[red, rotate=-90, transform shape] at (2.75,-1.5) (C) {mygroup};
    \draw[->,blue] (A-s1) to[out=90,in=100] (B-s2);
    \draw[->,blue] (A-s3) to[out=-60,in=180] (C-s2.south);
\end{tikzpicture}
%
\end{document}

enter image description here

Update:

Can pics have parameters? Say for having the same shape but different labels.

Yes, but a new kind of pic declaration is needed. Next code shows how to declare 3 parameters to mygroup pic and how to assign them with mygroup={1st}{2nd}{3rd} syntax. In this answer to TikZ 3.0---Multiple arguments for `pic`, another sysntax is proposed mygroup={1st/2nd/3rd}. It's easy to adapt the code.

I'm sure it could be possible to define some default parameters, but until now I couldn't. I know how to do it with style declarations but I couldn't succeed with pic. Until I find a solution (or somebody else provides it) you'll have to declare all three parameters for every group.

\documentclass[border=6mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
%

\tikzset{
    pics/mygroup/.style n args={3}{
        code = {
                \draw (0,0) coordinate (-center) circle (1.5cm);
                \draw (150:0.75) node (-s1) {#1}
                    (30:.75) node (-s2) {#2}
                    (-90:.75) node (-s3) {#3}
                    (-s1.center) edge[->,shorten >=3mm, shorten <=3mm] (-s2.center)
                                        edge[->,shorten >=3mm, shorten <=3mm] (-s3.center)
                    (-s2.center) edge[->,shorten >=3mm, shorten <=3mm] (-s3.center);
        }
    }
}
\begin{tikzpicture}[>=latex]
    \pic (A) {mygroup={$S_1$}{$S_2$}{$S_3$}};
   \pic[rotate=15,transform shape] at (3,2) (B) {mygroup={$S_5$}{$S_6$}{$S_7$}};
   \pic[red, rotate=-90, transform shape] at (2.75,-1.5) (C) {mygroup={$S_a$}{$S_b$}{$S_c$}};
    \draw[->,blue] (A-s1) to[out=90,in=100] (B-s2);
    \draw[->,blue] (A-s3) to[out=-60,in=180] (C-s2.south);
\end{tikzpicture}

\end{document}

enter image description here

4
  • Very nice. Didn't had a look at the ''pic'' environment yet and did it with a new scope definition (till now). Like your answer.
    – moospit
    Apr 10, 2014 at 7:35
  • I was considering asking a separate question about the grouping idea itself. However, I do appreciate your feedback as it is useful. None the less, Harish is now busy, are you able to answer the extension I've added to my question about arcs? Apr 12, 2014 at 1:00
  • Can pics have parameters? Say for having the same shape but different labels. Apr 15, 2014 at 3:24
  • @GeoffPointer: Please, look at updated answer.
    – Ignasi
    Apr 15, 2014 at 7:16
2

When (re)using groups i use the following approach. It let's you create a group and reuse it everywhere with custom x,y-shift and size.

\documentclass[border=6mm]{standalone}
\usepackage{tikz}

\begin{document}

% define a new group of elements to be reused later
\def\mygroup#1#2{
\begin{scope}[shift={#1}, scale=#2]
  % using polar coordinates here (just for example)
  \draw (0,0) ++(135:1cm) node (n1) {$S_1$};
  \draw (0,0) ++(45:1cm) node (n2) {$S_2$};
  \draw (0,0) ++(270:1cm) node (n3) {$S_3$};

  \draw [->] (n1) -- (n2);
  \draw [->] (n2) -- (n3);
  \draw [->] (n1) -- (n3);
\end{scope}
}

\begin{tikzpicture}[>=latex]
  \draw (0,0) circle (1.5cm); 
  % reuse \mygroup (1st parameter is x,y-shift, 2nd is resize)
  \mygroup{(0,0)}{1};
\end{tikzpicture}
\end{document}

enter image description here

This way you can reuse the group e.g also in other groups and subclass parts of you tikz-code.

EDIT (Version with arcs):

Here is a enhanced version of your MWE with arcs. The way it's done here you can shift the triangle figure by x,y-coordinates and the corresponding arcs stay at the desired nodes. I just added node names to the three nodes (n1, n2, n3) and set the arc position relative to them.

\documentclass[border=6mm]{standalone}
\usepackage{tikz}

\begin{document}
%
\begin{tikzpicture}[>=latex]
    \draw (1.5,1.5) circle (2.0cm);
    \draw (0.5,1.8) node (n1) {$S_1$}
        +(2,0) node (n2) {$S_2$}
        +(1,-1) node (n3) {$S_3$}
        +(0.4,0) edge[<->] +(1.6,0)
        +(1.8,-0.20) edge[<->] +(1.2,-0.8)
        +(0.2,-0.2) edge[<->] +(0.8,-0.8);
    \draw[<->] (n1.north) arc (0:270:0.3cm);
    \draw[<->] (n2.east) arc (-90:180:0.3cm);
    \draw[<->] (n3.south) ++(.2,.1) arc (45:-225:0.3cm);
\end{tikzpicture}
%
\end{document}

It wasn't possible to me to get all path and node definitions into one call. The arcs won't have the arrowheads if added without the extra draw.

I think the preferred way is to create a new shape by \def or the .pic-environment like shown above. If you try to put all path and node definitions into one call, you wont be able to fine tune your graphic. Also it will be harder to reuse the code in other contexts.

EDIT: Support for circular coordinates around node (See also comment below) The following code is the answer to the comments below. It introduces support for circular coordinates around a node replacing the north, south,... coordinates.

Here is a small snippet that shows how you can use polar coordinates to achieve your goal:

\documentclass[border=6mm]{standalone}
\usepackage{tikz}

\begin{document}
%
\begin{tikzpicture}[>=latex]
    \draw (0,0) node (n3) {$S_3$};
    \draw [dashed, red] (n3.east) |- (n3.south) -| (n3.west);
    \draw [red, fill=red] (n3.south) circle (2pt);
    \draw [red, fill=red] (n3.south east) circle (2pt);
    \draw [red, fill=red] (n3.south west) circle (2pt);

    \draw [dashed, blue] (0,0) ++(-.5,0) arc (180:360:.5cm);
    \draw [blue, fill=blue] (n3) ++(-90:.5cm) circle (2pt);
    \draw [blue, fill=blue] (n3) ++(-45:.5cm) circle (2pt);
    \draw [blue, fill=blue] (n3) ++(-135:.5cm) circle (2pt);
\end{tikzpicture}
%
\end{document}

Polar coordinates around node

4
  • Please see this comment as it applies equally to you. Thank you. Apr 12, 2014 at 1:02
  • Updated my solution by your MWE including arcs fixed to the nodes. The arcs are single draws but they align to the node positions.
    – moospit
    Apr 13, 2014 at 10:04
  • What you've shown is what I ended up trying myself. It's funny how there's always at least one that you end up having to tweeze around somewhat. One thing I find a bit annoying about tikz anchors is that they're on a rectangle not a circle. I'd prefer south east to be the same distance from the centre as south. Do you know if there was a special reason for that? Anyway the relative positions for the arcs works well and it's good that I now have a strategy for them, although in this case I've decided I prefer the bends because they're more compact. Thanks for your feedback. Apr 14, 2014 at 3:10
  • 1
    If you want to use the same distance from the center you can make use of polar coordinates. Instead of (n3.south) you can use (n3) ++(-90:.5cm). This gives you the point .5cm below n3. So you can do for the other points and set them circular around: (n3) ++(-45:.5cm) or (n3) ++(-135:.5cm) for the custom south east or south west.
    – moospit
    Apr 14, 2014 at 5:28

You must log in to answer this question.

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