4

i use pgfplots to create plots of huge data sets. It reads from csv-files with about 13000 lines. What I want to achieve is to show the y-Value on a given x-value.

Hope this picture describes, what I want to achieve:

enter image description here

This is, what I do to create the plots:

\documentclass[]{beamer}
\usepackage[eulergreek]{sansmath}
\setbeamertemplate{navigation symbols}{}

\usepackage{pgfplots}
\pgfplotsset{%
    compat=newest,
    tick label style={font=\sffamily},
    xticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
    yticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
}


\begin{document}
\begin{frame}
    \begin{tikzpicture}
        \begin{axis}[
                font={\sffamily},
                every axis label/.append style={font=\sffamily\footnotesize},
                width=\textwidth,
                axis line style=thin,
                axis line style={gray!30},
                axis y line = center,
                axis x line = center,
                tick label style={font={\sansmath\sffamily\fontsize{4}{4}\selectfont}},
                x label style={at={(axis description cs:1.0,-0.03)},anchor=north, font={\tiny}},
                y label style={at={(axis description cs:-0.08,.5)},rotate=90,anchor=south, font={\tiny}},
                xlabel=time,
                ylabel=values,
                every y tick/.style={gray!30},
                ytick={-550,-500,...,1350},
                xtick={0,1000,...,12840},
                no markers,
                every axis plot/.append style={ultra thin},
                every axis/.append style={font=\sffamily},
                axis on top=false,
                font={\sffamily},
                xmin=0, xmax=12900,
                ymin=-550, ymax=1350,
            ]
            \addplot  table[col sep=semicolon, x index = {0}, y index = {1}]{P1.CSV};
        \end{axis}
    \end{tikzpicture}
\end{frame}

\end{document}

Is there a way to do this automatically without putting the y-value in the graph manually? I don't even have an idea for search words I could google.

5
  • It looks like the points you want marked are the extremas, I would have a look at tex.stackexchange.com/questions/46176/… Dec 6 '17 at 11:24
  • Thanks for the hint. Unfortunately I gave these points just as examples but I would need the y-values on different x-positions. Dec 6 '17 at 11:37
  • Would it be OK to give the index (i.e. row number in file) instead of x-value? Dec 6 '17 at 11:51
  • Would be ok, yes. Dec 6 '17 at 12:59
  • When replying to a specific user, it's generally best to write an at-sign followed by the username, e.g. @schmendrich, otherwise that user wont be notified. Tab-completion of usernames is available, you can only ping one user per comment. (You as the owner of the post is always notified of new comments.) Dec 6 '17 at 13:29
4

You can use a second \addplot that only plots at given row numbers (or rather, at specific \coordindexes), due to an x filter:

\addplot [only marks,mark=*,mark size=1pt,
          nodes near coords,
          x filter/.code={
          \ifnum \coordindex=150
          \else
            \ifnum \coordindex=380
            \else
              \def\pgfmathresult{}
            \fi
           \fi                            
           }]
           table[x index = {0}, y index = {1}]{somedatafileIhadlyingaround.dat};

The \ifnums say that if \coordindex is either 150 or 380, then do nothing, otherwise do \def\pgfmathresult{} which means no point is plotted.

nodes near coords by default prints the y-value next to the point. You can change the style of those nodes with every node near coord/.style={...}.

You might want to add filter discard warning=false to the axis options if you don't want a lot of warnings about discarded coordinates in the .log file.

Note I commented settings for ticks and axis limits, as the datafile I used had a very different range.

output of code

\documentclass[]{beamer}
\usepackage[eulergreek]{sansmath}
\setbeamertemplate{navigation symbols}{}

\usepackage{pgfplots}
\pgfplotsset{%
    compat=newest,
    tick label style={font=\sffamily},
    xticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
    yticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
}


\begin{document}
\begin{frame}
    \begin{tikzpicture}
        \begin{axis}[
                font={\sffamily},
                every axis label/.append style={font=\sffamily\footnotesize},
                width=\textwidth,
                axis line style=thin,
                axis line style={gray!30},
                axis y line = center,
                axis x line = center,
                tick label style={font={\sansmath\sffamily\fontsize{4}{4}\selectfont}},
                x label style={at={(axis description cs:1.0,-0.03)},anchor=north, font={\tiny}},
                y label style={at={(axis description cs:-0.08,.5)},rotate=90,anchor=south, font={\tiny}},
                xlabel=time,
                ylabel=values,
                every y tick/.style={gray!30},
%                ytick={-550,-500,...,1350},
%                xtick={0,1000,...,12840},
                every axis plot/.append style={ultra thin},
                every axis/.append style={font=\sffamily},
                axis on top=false,
                font={\sffamily},
%                xmin=0, xmax=12900,
%                ymin=-550, ymax=1350,
                filter discard warning=false  % <-- disables warnings about discarded coordinates
            ]
            % note +[mark=none], and removed "no markers" from axis options
            \addplot +[mark=none] table[x index = {0}, y index = {1}]{somedatafileIhadlyingaround.dat};
            % add second plot for marks and labels
            \addplot [only marks,mark=*,mark size=1pt,
                      nodes near coords,
                      x filter/.code={
                         \ifnum \coordindex=150
                         \else
                            \ifnum \coordindex=380
                            \else
                               \def\pgfmathresult{}
                            \fi
                         \fi                            
                     }]
                     table[x index = {0}, y index = {1}]{somedatafileIhadlyingaround.dat};
        \end{axis}
    \end{tikzpicture}
\end{frame}

\end{document}
0
2

Consider as an alternative this Asymptote MWE:

// ylabs.asy
// 
// run 
// asy ylabs.asy
// 
// to get ylabs.pdf image
// 
settings.tex="pdflatex";

import graph;
size(10cm,8cm,IgnoreAspect);
import fontsize;defaultpen(fontsize(8pt));
texpreamble("\usepackage{lmodern}");
pen linePen=deepblue+0.8bp;

string data="p15000.csv";
file in=input(data).line().csv();
real[][] a=in; a=transpose(a);
real[] xPos=    {0.38    , 0.53     , 0.7     ,};
pair[] labelPos={plain.E, plain.W, plain.NE,};
guide g=graph(a[0],a[1]);
draw(g,linePen);
xaxis("Time",0,1.2,RightTicks(Step=0.1,step=0.05,OmitTick(0)));
yaxis("Values",LeftTicks(Step=100,step=50));

real[] t; pair p;
// adding a point of the minimum to the list
t=mintimes(g); 
p=point(g,t[1]);
xPos.push(p.x);
labelPos.push(plain.S);
// adding a point of the maximum to the list
t=maxtimes(g); 
p=point(g,t[1]);
xPos.push(p.x);
labelPos.push(plain.N);

for(int i=0;i<xPos.length;++i){
    t=times(g,xPos[i]);
    p=point(g,t[0]);
    dot(p,UnFill);
    label("$"+format("%4i",round(p.y))+"$",p,labelPos[i]);
}
shipout(bbox(Fill(paleyellow)));

The placement of the marks is governed by their positions collected in xPos array and their corresponding orientation in labelPos array. Also a code included to automatically find and add marks for the min/max y value (the orientations of the labels are also added manually).

This MWE was tested with about 15000 sample points of data in p15000.csv file with no problems, here is the result:

enter image description here

This smaller points.csv file which produces similar shape can be used for testing :

0.007,4.149
0.075,0
0.111,-141.079
0.175,-331.95
0.245,-468.88
0.278,-506.224
0.358,-477.178
0.377,-460.581
0.392,-70.539
0.394,4.149
0.441,4.149
0.519,0
0.521,112.033
0.601,946.058
0.604,875.519
0.625,867.22
0.663,829.876
0.769,800.83
0.764,721.992
0.781,639.004
0.795,-49.793
0.816,4.149
0.84,4.149
0.863,4.149
0.901,-58.091
0.927,4.149
0.96,0
1.047,4.149
1.13,0
2
  • Stunning. I just don't understand the code ;-) Never used Asymptote before. Dec 7 '17 at 8:03
  • @schmendrich: Asymptote has its roots in METAPOST, but its code uses C++/python-like commands, for example, real[] xPos={0.38,0.53,0.7,}; declares an array of real values and initializes it with 3 values. After that xPos[0] will be set to 0.38; for(int i=0;i<xPos.length;++i) is a basic for-loop to run i from 0 to xPos.length, etc. Does it really look cryptic? Anyway, feel free to ask, if interested.
    – g.kov
    Dec 7 '17 at 12:33

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.