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 04 '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 04 '14 at 18:44

2 Answers2

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}
Jake
  • 232,450
  • 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 04 '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 04 '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 04 '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 04 '14 at 18:36
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

  • Elegant "linear interpolation algorithm" ;) – Jake Aug 04 '14 at 19:01
  • Very interesting and well done, but could you tweak that to avoid node overlay? – user1790813 Aug 04 '14 at 20:21
  • give a data set as example –  Aug 04 '14 at 20:22
  • Sure. I updated the example in the original question. – user1790813 Aug 04 '14 at 21:49
  • 1
    see my edited answer. I have no idea what do you really expect if nodes are multiple defined. –  Aug 05 '14 at 07:13
  • Sorry, it is irrelevant. I noticed that liftpen=2 is permanently attached to \psellipticarc(n) so we cannot change it to liftpen=0 or liftpen=1. See my MWE here(click). – kiss my armpit Aug 05 '14 at 08:11
  • @Herbert that solution would be perfect if instead of the last one it showed the first one! However when I run it I get lots of errors like this

    MiKTeX GPL Ghostscript 9.05: Unrecoverable error, exit code 1 and this

    ** WARNING ** Filtering file via command -->mgs.exe -q (...) -c quit<-- failed. ** WARNING ** Image format conversion for PSTricks failed. ** WARNING ** Interpreting special command pst: (ps:) failed. ** WARNING ** >> at page="1" position="(153.919, 460.974)" (in PDF)....

    It also doesn't recognize \SaveDataAsNodes.

    – user1790813 Aug 05 '14 at 09:49
  • @user1790813: I changed the order of the nodes (see answer). You have to run the example with xelatex and, of course, to use the latest pst-node.tex from http://texnik.dante.de/tex/generic/pst-node/ (will be available on TeXLive/MikTeX tommorrow, hopefully –  Aug 05 '14 at 09:57
  • @Herbert thanks a lot for your help. Concerning technical details, I am using TeXStudio with XeLaTeX from MiKTeX 2.9. I think the program installed automatically pst-node, but I will check and maybe try doing it by hand. Thanks a lot once again. – user1790813 Aug 05 '14 at 10:22
  • @user1790813: yes, but updates may take some days. Until that you can save the current pst-node.tex in your documents directory and delete it later. –  Aug 05 '14 at 10:24
  • @Herbert I have decided to play a bit with the header and currently I am using this one

    \usepackage{pstricks} \usepackage{pst-node,pst-plot} \usepackage{pst-plot} \usepackage{pst-node} \include{pst-node.tex} \include{pst-node.sty} \include{pst-node97.tex}

    the "include" are the files that I have downloaded manually and placed into my project directory. I haven't downloaded the whole package. I went to the website you mention earlier and picked those files individually. Still there are many commands that XeLaTeX does not recognize.

    – user1790813 Aug 05 '14 at 11:05
  • That is not a good way. You should save only the pst-node.tex and then using xelatex with my example. Your do not need other packages. However, it is easy to replace the current pst-node.tex with the new one. Run in a dos box kpsewhich pst-node.tex and it shows you the directory where the file is saved. –  Aug 05 '14 at 11:10
  • https://drive.google.com/file/d/0B82XQTkAkC3wM1Z1N3RIN1djZlE/edit?usp=sharing

    @Herbert This is a screenshot of my TeXStudio session. The words in red are the ones that are not being recognized. In the right you have the pdf output of XeLaTeX. At bottom left you have a part of the many error messages. I don't know if that helps much but I don't know what else I can do.

    – user1790813 Aug 05 '14 at 11:32
  • I installed MikTeX 2.9 and TeXStudio. Edited TeXStudio to use xelatex as compiler, restart it and had success. Then I used \usepackage[crop=off]{auto-pst-pdf} and run pdflatex -shell-escape <file> which also worked successfully. However, I always addeded as optional argument for xelatex and pdflatex -shell-escape. Via the menu Options->Configure. And I had the new pst-node.tex in the documents directory. –  Aug 05 '14 at 12:51
  • Thanks a lot for the help. In the end I managed to compile the file using LaTeX and the DVI -> PS -> PDF chain. – user1790813 Aug 05 '14 at 14:56
  • 1
    That is fine. See also my extended answer for marking the line connections. –  Aug 05 '14 at 16:44