19

In pgfplots is it possible to have several plots in one datafile?

The goal is to add about 20 plots, which has different number of points and not the same x-value, to the same axis. (app. 350 points)


One posible solution is to have the plots in separate column, and then use loads of 'nan' because of the different x values:

    x  p1   p2  P3  ...
    1  3    nan nan ...
    2  nan  5   nan ...
    6  4    8   nan ...
    8  7    nan nan ...
    ...

I do not like this solution:o(


The gnuplot solution is nice: the different plots are separated in the datafile by two newlines, and they are selected by 'index'. Does something similar exist in pgfplots? or any other solution?

  • What program / method do you use to generate the datafiles? – Jake Dec 08 '11 at 10:38
  • I've only ever tried this with one axis shared by all plots, so I'm not sure. Why do you want only one file though? – qubyte Dec 08 '11 at 10:51
  • @MarkS.Everitt: I think Hans-Peter also wants the plots to be on the same axis, but they won't be defined at the same x-values. – Jake Dec 08 '11 at 10:54
  • The data are collected from different scientific articles, so there are no generating program. I would like them plotted on the same axis. – hpekristiansen Dec 08 '11 at 11:05
  • Oh, I see. Well that's easy then! Hang on... – qubyte Dec 08 '11 at 11:09
  • See my updated entry. You can put all of your data into a single file with uneven columns. Even so, I'd recommend keeping them in separate files though if you can. – qubyte Dec 08 '11 at 11:57

3 Answers3

12

You can use the \addplot command multiple times on the same axes. The files that the different \addplots take can be the same or different, and different columns etc.

\pgfplotsset{width=6cm,compat=newest}
\begin{axis}[
    scale only axis,
    xlabel={$\tau$ ($\mu$s)},
    ylabel={P(bitflip)},
    ymin=0,
    ymax=1,
    xmin=0,
    xmax=125.66,
]
\addplot[color=red]
    table[x=time,y=fidelity] {data1.txt};
\addplot[color=black]
    table[x=time,y=fidelity] {data1.txt};
\end{axis}
\end{tikzpicture}

It's not so clear here, but I used data from two sample files to plot this

enter image description here

The data files here are indexed by column headers, but you can also do this by number. One of the files begins with the following lines:

time    fidelity
0.00000000e+00  0.00000000e+00
2.02874597e-01  9.75413405e-05
5.19896845e-01  4.76482130e-04
8.36998426e-01  7.26895359e-04
1.15410184e+00  7.52986468e-04
1.47115744e+00  8.85559658e-04

You can put multiple columns in one file, and gaps (just whitespace) are tolerated. In the following plot one data file is used with four columns, and there are clear gaps in the time and amplitude entries for the red plot.

enter image description here

\pgfplotsset{width=6cm,compat=newest}
\begin{tikzpicture}
\begin{axis}[
    scale only axis,
    xlabel={$\tau$ (ns)},
    ylabel={Negativity},
    ymin=-1,
    ymax=1,
    xmin=0,
    xmax=6.3,
    legend style={font=\small,at={(0.5,0.96)},anchor=north,style={nodes={right}}},
]
\addplot[color=black]
    table[x index=0,y index=1] {data.txt};
\addplot[color=red]
    table[x index=2,y index=3] {data.txt};
\end{axis}
\end{tikzpicture}

Note that there are no column headers this time (just for variety). Gaps look like

2.28479466e+00  7.55749574e-01  -6.54860734e-01 2.28479466e+00  
2.34826118e+00  7.12694171e-01  -7.01474888e-01 2.34826118e+00  
2.41172769e+00  6.66769001e-01  -7.45264450e-01 2.41172769e+00  
2.47519421e+00  6.18158986e-01      
2.53866073e+00  5.67059864e-01      
2.60212725e+00  5.13677392e-01      
2.66559377e+00  4.58226522e-01      
2.72906028e+00  4.00930535e-01      
2.79252680e+00  3.42020143e-01      
2.85599332e+00  2.81732557e-01      
2.91945984e+00  2.20310533e-01      
2.98292636e+00  1.58001396e-01      
3.04639288e+00  9.50560433e-02      
3.10985939e+00  3.17279335e-02      
3.17332591e+00  -3.17279335e-02     
3.23679243e+00  -9.50560433e-02     
3.30025895e+00  -1.58001396e-01     
3.36372547e+00  -2.20310533e-01     
3.42719199e+00  -2.81732557e-01     
3.49065850e+00  -3.42020143e-01     
3.55412502e+00  -4.00930535e-01     
3.61759154e+00  -4.58226522e-01 -8.88835449e-01 3.61759154e+00  
3.68105806e+00  -5.13677392e-01 -8.57983413e-01 3.68105806e+00  
3.74452458e+00  -5.67059864e-01 -8.23676581e-01 3.74452458e+00  
3.80799110e+00  -6.18158986e-01 -7.86053095e-01 3.80799110e+00

It should also be fine to have uneven columns, provided the number of tabs or commas is correct.

qubyte
  • 17,299
  • Yes - that was my idea, but it involves loads of loads of 'nan' because of the different x-values. -or maybe I do not understand. – hpekristiansen Dec 08 '11 at 11:21
  • But wouldn't this solution require one datafile per plot? If I understand correctly, Hans-Peter wants to be able to generate several different plots (with different number of data points and different sampling intervals) from a single data.csv file. – Jake Dec 08 '11 at 11:22
  • Nope. See my update. pgfplots doesn't care about missed columns, so long as the number of tabs or commas is correct. At least that's what my basic trials showed. Not sure if it'll stand up to too much abuse. This is similarly true of uneven column lengths. – qubyte Dec 08 '11 at 11:50
  • Oh yeah, okay, but the problem that you have to provide the right number of somethings, be they nan or tabs or commas, would remain with this approach. – Jake Dec 08 '11 at 12:03
  • @Jake: Then the answer is simple. Place the columns in descending order of length, or script a solution to add in the extra tabs or columns. That should not be difficult. – qubyte Dec 08 '11 at 12:06
  • You are right 'nan' is not necessary. In my case I have (cat HSI.dat |cut -sf 1|sort -n|uniq|wc -l) 98 different x-values, and 20 plots giving a table of 1960 entries for only 350 points... and a lot of work to interleave my datafile. – hpekristiansen Dec 08 '11 at 12:13
  • This way interleaving should not be necessary, as long as you're happy to provide x and y axes every time. i.e. assuming that you're not using one axis with integers and reusing some values for multiple plots (seems unlikely). – qubyte Dec 08 '11 at 12:17
  • @MarkS.Everitt: Yeah, or you could just collect all the series in an Excel or OpenOffice spreadsheet and save it as a csv, which will take care of the right number of field separators. Thinking about it, I guess your approach is preferable to the \addplot gnuplot method because of the ability to use column names instead of just indexes. – Jake Dec 08 '11 at 12:25
  • that would give a table of 350*20=7000 entries for only 350 points:o) – hpekristiansen Dec 08 '11 at 12:26
  • @Hans-PeterE.Kristiansen: You might want to think of converting your datafile to a file like Mark suggests, it'll make the maintenance of the datafile a lot easier ("What was the 16th block of data again?"). – Jake Dec 08 '11 at 12:28
  • True pgplots(or gnuplot) does not know what index x is, but I have a comment in the datafile itself. – hpekristiansen Dec 08 '11 at 12:31
  • Not necessary. See my second example. You can index by column (starting with zero). – qubyte Dec 08 '11 at 13:02
  • @MarkS.Everitt: The table solution without nan does not work, because any number of tabs will only be read as one. – hpekristiansen Dec 09 '11 at 09:46
  • So ragged bottom doesn't work? How about with columns in order of descending size? Commas? – qubyte Dec 09 '11 at 11:21
10

You can use gnuplot in the background by using \addplot gnuplot [raw gnuplot] {<gnuplot commands>};:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}

\begin{filecontents*}{data.txt}
1 1
2 4
3 9
4 16
5 25


1 1
2.5 5
6 12
\end{filecontents*}


\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot gnuplot [raw gnuplot] {plot 'data.txt' index 0};
\addplot gnuplot [raw gnuplot] {plot 'data.txt' index 1};
\end{axis}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
  • OK cool. I think that is the solution. I will try. The manual pretends that the gnuplot mode is only for function plotting:o) – hpekristiansen Dec 08 '11 at 11:25
  • Is it described somewhere exactly how much gnuplot is in the background. Who is in control of point/line type/color, .... – hpekristiansen Dec 08 '11 at 11:35
  • It's all PGFplots, all gnuplot does is generate a data file that is then read in PGFplots using \addplot file .... From the PGFplots manual: "In contrast to plot expression, the plot gnuplot command employs the external program gnuplot to compute coordinates. The resulting coordinates are written to a text file which will be plotted with plot file". – Jake Dec 08 '11 at 11:37
  • Ok thank you. I knew that was the case with a function passed to gnuplot, but of cause its the same here. – hpekristiansen Dec 08 '11 at 11:49
2

The other answers weren't immediately clear to me. After struggling for a bit, I found that it's very easy to draw multiple lines from the same file.

You can simply put white lines in your data file and you're done:

\documentclass[]{article}
\usepackage{filecontents,pgfplots}

\begin{filecontents}{test.dat} x y 1 0.5 2 0.5 2 1 1 1 1 0.5

1 2.5 2 2.5 2 3 1 3 1 2.5 \end{filecontents}

\begin{document} \begin{tikzpicture}[scale=1] \begin{axis} [ axis lines=left, axis line style={->}, xmin=0,xmax=5, ymin=0,ymax=5 ] \addplot [] table [x=x, y=y] {test.dat}; % Plot all shapes in data file \end{axis} \end{tikzpicture} \end{document}

Which gives two separately drawn lines:

Two lines in one graph

Hope this speeds up someone's search for an answer ;)

Jean-Paul
  • 421