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'm trying to make a plot similar to this one but I'm having a really hard time. If anyone can help me getting the details, I'll appreciate.

enter image description here

I thought I couldn't post questions like this, but as I've seen some questions like those asking for plots similar to xkcd's, I believe it might be OK.

My far-from-good example is here. My circle has a radius=sqrt(2), but it really doesn't matter.

\documentclass{article}

\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{tikzpicture}

\begin{axis}[
height=20cm,
width=20cm,
xmin=-2.5, xmax=2.5,
ymin=-2.5, ymax=2.5,
only marks,
axis x line=none,
axis y line=none
]

\draw (axis cs:0,0) circle[radius=1.41421356237];

% circle
\addplot [mark=*, mark size=0.3cm,color=red]
coordinates {
(-1,-1)
(1,1)
};
\addplot [mark=*, mark size=0.3cm,color=red]
coordinates {
(-1,1)
(1,-1)
};
% black arrows
\addplot [mark=none,color=black,
quiver={u={x}, v={-x},scale arrows=0.4}, ->]
coordinates {
(-1,-1)
(1,1)
};
\addplot [mark=none,color=black,
quiver={u={-x}, v={-x},scale arrows=0.4}, ->]
coordinates {
(-1,1)
(1,-1)
};
% blue arrows
\addplot [mark=none,color=blue,
quiver={u={x}, v={-x-0.5},scale arrows=0.5}, ->]
coordinates {
(-1,-1)
(1,1)
};
\addplot [mark=none,color=blue,
quiver={u={-x}, v={-x-0.5},scale arrows=0.5}, ->]
coordinates {
(-1,1)
(1,-1)
};

\addplot [mark=*, mark size=0.3cm,color=blue] coordinates {
(1.41421356237,0)
(-1.41421356237,0)
(0,1.41421356237)
(0,-1.41421356237)
(1.41421356237,0)
};

\end{axis}  
\end{tikzpicture}
\end{document}

which gives me this:

enter image description here

share|improve this question
    
Do the green and red touching arrows have the same length? –  Sigur Jan 28 '13 at 22:31
    
@Sigur, yes, all arrows have the same lenght. –  perr0 Jan 28 '13 at 22:43
    
And do you have only those circles or you want some code more flexible to works with more circles? –  Sigur Jan 28 '13 at 22:45
3  
Why use pgfplots? Such figures are better drawn using pgf/tikz or metapost. –  Aditya Jan 28 '13 at 23:14
1  
Tikz is the higher level language for pgf. Pgfplots is for frawing data plots, not diagrams. Metapost is much older than pgf, and much better at doing calculations. Other alternatives are pstricks (which inspite of the name works with pdftex as well) and asymptote (metapost with a c-like syntax). –  Aditya Jan 29 '13 at 14:00

2 Answers 2

up vote 11 down vote accepted

Instead of pgfplots construction, you can use an alternating style which are slightly verbose here (repetition of ->, ultra thin etc.) Luckily the structure is easy to identify. You can furnish further according to your needs.

EDIT: Thanks to JLDiaz' color-seeing eyes, I took a stab on the green arrows. Hope it hits the right one :)

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}[>=latex,
cnode/.style={circle,inner sep=3pt,outer sep=0},
myline/.style={ultra thin,->}
]
\def\myarrowlen{5mm}
\pgfmathsetmacro{\myradius}{sqrt(2)}

\node[draw,circle,minimum size=2*\myradius cm] (bigc) at (0,0) {\tiny +};

\foreach \x in {1,...,8}{
\ifodd\x\relax
    \node[cnode,fill=red] (n-\x) at (bigc.45*\x) {};
    \draw[red,myline] (n-\x)  -- ($(n-\x)!-\myarrowlen!(bigc.45*\x+45)$);
    \draw[red,myline] (n-\x)  -- ($(n-\x)! \myarrowlen!(bigc.45*\x+45)$);
\else
    \node[cnode,fill=blue] (n-\x) at (45*\x:\myradius) {};
    \draw[blue , myline] (n-\x) -- ($(n-\x)!-\myarrowlen!(bigc.45*\x+45)$);
    \draw[green, myline] (n-\x) -- ($(n-\x)! \myarrowlen!(bigc.45*\x-45)$);
    \draw[     , myline] (n-\x) -- ++({45*(\x-2)}:\myarrowlen);
\fi
}
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
Hmm... Colorblind here and in the comments green and red are mentioned, sorry in advance. –  percusse Jan 29 '13 at 0:26
    
The green arrows are the third (the ones at -45) in the blue circles. By the way, great answer! (+1) –  JLDiaz Jan 29 '13 at 0:58
    
@JLDiaz Thank you very much for the pointer :) –  percusse Jan 29 '13 at 1:11
    
Thank you! This answer is really simple. Just to add to this colorblindness stuff, the arrow pointing from the red circle to the blue circle (opposite to green) is actually brown. ;) –  perr0 Jan 29 '13 at 12:22
    
@percuße, your example works flawlessly in a standalone file. But when I embed it in my main document (with an \input command) it gives the error: "Package pgf Error: No shape named current axis is known \end{tikzpicture}". So I tried editing your code and included an empty \being{axis} \end{axis} and it compiles with no errors (but it draws the axis, of course). Also I noted that, despite the error, the figure is drawn in the main document. Although, as I use tikz externalize, the separate pdf file is not created. Do you know why this is hapenning? –  perr0 Jan 29 '13 at 15:02

Here is an alternative solution using metapost (I used ConTeXt, but you can use standalone metapost, or metapost embedded in LaTeX as well).

The main difference from percusse's solution is that instead of specifying the length and angle of the arrows, I calculate it based on the location of the nodes. Unlike TikZ, metapost does not provide a nice way to shorten paths, so I define a macro that does that.

\startMPinclusions
  vardef shorten(expr p, q, d) =
    % p = start point
    % q = end point
    % d  = distance
    newpair qq;
    qq := q - d*dir(angle(q-p));
    (p -- qq)
  enddef;
\stopMPinclusions
\starttext
\startMPpage[offset=3mm]
  newnumeric u; u := 2cm; % Radius of the circle
  newnumeric w; w := 3mm; % Radius of nodes
  newnumeric d; d := 0.25mm; % Distance between arrows

  draw fullcircle scaled (2*u);

  newpath node;
  node := fullcircle scaled w;

  % Use 10 points to avoid modular arithematic
  for i = 0 upto 10 : 
      z[i] = u*dir(45*i);
  endfor

  newpair mid_point ;
  newpair scratch_point ;
  newnumeric tangent_angle;

  for i = 1 upto 8 :
    if i mod 2 = 0 : % blue node
      % Caclulate coordinates
      mid_point := 0.5[z[i], z[i-1]];
      scratch_point := 2*z[i] - 0.5(z[i] + z[i+1]);

      % Draw arrows
      drawarrow shorten(z[i], mid_point, d) withcolor green;
      drawarrow shorten(z[i], scratch_point, d) withcolor blue;

      tangent_angle := angle(0.5[mid_point, scratch_point] - z[i]);
      scratch_point := z[i] + abs(z[i] - mid_point)*dir(tangent_angle);

      drawarrow shorten(z[i], scratch_point, d) withcolor black;

      % Draw node
      fill node shifted z[i] withcolor blue;
    else : % red node
      % Caclulate coordinates
      mid_point := 0.5[z[i], z[i+1]];
      scratch_point := 2*z[i] - mid_point ;

      % Draw arrows
      drawarrow shorten(z[i], mid_point, d) withcolor red;
      drawarrow shorten(z[i], scratch_point, d) withcolor red;

      % Draw node
      fill node shifted z[i] withcolor red;
    fi
  endfor

\stopMPpage
\stoptext

enter image description here

share|improve this answer
1  
After ConTeXt now I feel the need to learn MetaPost thanks to you. Let me finish my thesis please :P –  percusse Jan 29 '13 at 18:45

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.