9

I have a few files in the following format:

x   y
12  12
12  13
13  15
15  15
15  13
13  12
12  10
10  8
8   8
8   10
10  12
12  12
12  10
10  10

And I wanted to plot them as a directed graph in a .tex file using pgfplots.

The code I am currently using is this one

\usepackage{pgfplots}

\begin{center}
\begin{tikzpicture}
\begin{axis}[title=File1,
             xlabel={},
             ylabel={}]
\addplot table {data-1.txt};
\end{axis}
\end{tikzpicture}
\end{center}

This plots the points with lines between them but it is not enough for what I need. I would like to

  1. Set a different color for the first point
  2. Have arrows indicating between the dots indicating the "path" the dots take.

Some files (as the one in the example) may have overlapping nodes. If your solution could handle this scenario it would save me a lot of effort.

Another thing that I would like to do would be to do a linear interpolation of the points in the D-Graph that is generated. However I am totally clueless about how I am going to do that. I know that this seems rather awkward and might even be impossible with the most common linear interpolation algorithms, but if you could lend me a hand in that I would be very grateful.

As an example of the process described above, I would like to get something similar to this:

None

  • I'm not sure I understand what you want the result of the linear interpolation to look like. Could you maybe post a mockup of what you want the final result to look like? – Jake Aug 4 '14 at 17:56
  • 1
    Thanks for the picture. I've edited my answer to show how you can use the linear regression feature of PGFPlots to achieve this. – Jake Aug 4 '14 at 18:44
7

A solution with PSTricks. It needs http://texnik.dante.de/tex/generic/pst-node/pst-node.tex Run it with xelatex:

\documentclass[a4paper]{article}
\usepackage{filecontents}
\begin{filecontents*}{node.data}
12  12
12  13
13  15
15  15
15  13
13  12
12  10
10  8
8   8
8   10
\end{filecontents*}

\usepackage{pst-node,pst-plot}

\begin{document}
\begin{pspicture}(6.5,6.5)(16,16)
  \psaxes[axesstyle=frame,ticksize=0 9cm,tickcolor=black!20,Ox=7,Oy=7](7,7)(16,16)
  \saveDataAsNodes{node.data}{N}
  \psset{radius=2.5mm,arrows=->,arrowscale=1.5,nodesep=2.7mm,linewidth=1.3pt}
  \Cnodeput[linecolor=red]{0}(N0){foo}{0}
  \multido{\iA=1+1,\iB=0+1}{\numexpr\the\psLoopIndex-1}{%
    \Cnodeput{0}(N\iA){foo}{\iA}\ncline{N\iB}{N\iA}}
  \readdata\data{node.data}
  \listplot[plotstyle=LSM,linestyle=dashed,linecolor=blue,xStart=7,xEnd=16]{\data}
\end{pspicture}

\end{document}

enter image description here

The equation of the linear regression line can be plotted with \PstDebug=1:

enter image description here

The nodes are named N0... N9. Any connection with any offset between the nodes is possible.

A solution for multiple nodes which are overwritten, only the last one is printed:

\documentclass[a4paper]{article}
\usepackage{filecontents}
\begin{filecontents*}{node2.data}
12  12
12  13
13  15
15  15
15  13
13  12
12  10
10  8
8   8
8   10
10  12
12  12
12  10
10  10
\end{filecontents*}
\usepackage{pst-node,pst-plot}
\def\CPut(#1)#2{\pscircle*[linecolor=white](#1){3mm}\rput(#1){#2}\pscircle(#1){3mm}}

\begin{document}
\begin{pspicture}(6.5,6.5)(16,16)
  \psaxes[axesstyle=frame,ticksize=0 9cm,tickcolor=black!20,Ox=7,Oy=7](7,7)(16,16)
  \saveDataAsNodes{node2.data}{N}
  \psset{radius=2.5mm,arrows=->,arrowscale=1.5,nodesep=3mm,linewidth=1.3pt}
  \multido{\iA=\the\psLoopIndex+-1,\iB=\numexpr\the\psLoopIndex-1\relax+-1}%
     {\the\psLoopIndex}{\CPut(N\iA){\iA}\ncline{N\iB}{N\iA}}
  \pscircle*[linecolor=red](N0){3mm}\rput(N0){\bf\white0}
  \readdata\data{node2.data}
  \pslistplot[linecolor=blue,linestyle=dashed,plotstyle=LSM,xStart=7,xEnd=16]{\data}
\end{pspicture}
\end{document}

enter image description here

If you need some information on the connection itself use (\ncput):

  \multido{\iA=\the\psLoopIndex+-1,\iB=\numexpr\the\psLoopIndex-1\relax+-1}%
     {\the\psLoopIndex}{\CPut(N\iA){\iA}\ncline{N\iB}{N\iA}\ncput*[npos=0.4]{\tiny\iB/\iA}}

enter image description here

| improve this answer | |
  • Elegant "linear interpolation algorithm" ;) – Jake Aug 4 '14 at 19:01
  • Very interesting and well done, but could you tweak that to avoid node overlay? – user1790813 Aug 4 '14 at 20:21
  • give a data set as example – user2478 Aug 4 '14 at 20:22
  • 1
    see my edited answer. I have no idea what do you really expect if nodes are multiple defined. – user2478 Aug 5 '14 at 7:13
  • 1
    That is fine. See also my extended answer for marking the line connections. – user2478 Aug 5 '14 at 16:44
9

Here's an approach that uses the code from Gap between line and point in pgfplots, like pointintervalbox in gnuplot to draw arrows between the coordinates.

\documentclass[border=5mm]{standalone}

\usepackage{pgfplots, pgfplotstable}
\makeatletter
\pgfplotsset{
    discontinuous line/.code={
        \pgfkeysalso{mesh, shorten <=#1, shorten >=#1}
        \def\pgfplotsplothandlermesh@VISUALIZE@std@fill@andor@stroke{%
            \pgfplotspatchclass{\pgfplotsplothandlermesh@patchclass}{fill path}%
            \pgfplotsplothandlermesh@definecolor
            \pgfusepath{stroke}
            \pgfplotsplothandlermesh@show@normals@if@configured
        }%
    },
    discontinuous line/.default=1.5mm
}
\makeatother

\begin{document}

\pgfplotstableread{
x   y
12  12
12  13
13  15
15  15
15  13
13  12
12  10
10  8
8   8
8   10
}\datatable

\begin{tikzpicture}
\begin{axis}[
    title=File1,
    width=10cm
]
\addplot [
    discontinuous line=2.5mm,
    very thick, black, -latex,
    nodes near coords=\coordindex,
    every  node near coord/.style={
        draw,
        circle,
        anchor=center,
        inner sep=1.5pt,
        color={\ifnum\coordindex=0 red\else black\fi}
    }] table {\datatable};

\addplot [ultra thick, blue] table [y={create col/linear regression={y=y}}] {\datatable};
\end{axis}
\end{tikzpicture}

\end{document}
| improve this answer | |
  • Nice solution. Thanks! However, in some of the files there are points that overlap. Is there any way I can fix that or I will have to bear with two overlayed circles and numbers? Maybe I could only represent the points (with nothing inside) and add the numbers on top of the arrows. – user1790813 Aug 4 '14 at 18:29
  • @user1790813: That instantly becomes a much, much harder problem that's not easily solved using this approach. Depending on how many of these graphs you need to generate, I'd either go with a "proper" graph drawing software, or manual adjustments. – Jake Aug 4 '14 at 18:31
  • @user1790813: Concerning your edit: does that mean that your lines will never cross / the line labels would never overlap? Otherwise, you're just swapping one hard problem for another. – Jake Aug 4 '14 at 18:32
  • Yep. Didn't think about that. Maybe I will go for a more manual approach, but trying to use what I already have. Thanks. – user1790813 Aug 4 '14 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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