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 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

share|improve this question
    
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 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 at 18:44

2 Answers 2

up vote 8 down vote accepted

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

share|improve this answer
    
Elegant "linear interpolation algorithm" ;) –  Jake Aug 4 at 19:01
    
Much better, thanks for the edit! –  Jake Aug 4 at 19:57
    
Very interesting and well done, but could you tweak that to avoid node overlay? –  user1790813 Aug 4 at 20:21
1  
see my edited answer. I have no idea what do you really expect if nodes are multiple defined. –  Herbert Aug 5 at 7:13
1  
That is fine. See also my extended answer for marking the line connections. –  Herbert Aug 5 at 16:44

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}
share|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 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 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 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 at 18:36

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.