How to Plot CSV Columns with pgfplotsinvokeforeach
At a glance
- 1. Read the CSV
Load the file with pgfplotstableread and set col sep=comma.
- 2. Choose the columns
Put the names of the y-columns you want to plot in the foreach list.
- 3. Add each plot
Use #1 as the current y-column and specify the shared x-column.
- 4. Label the series
Add a legend entry inside the loop for each plotted column.
To plot several columns from one comma-separated file, read the file once as a PGFPlots table, then loop over the names of the columns you want to use as y-values. In the loop, #1 stands for the current column name. This is a convenient use of \pgfplotsinvokeforeach because its body can contain PGFPlots commands such as \addplot.
Complete example
The example below creates a small CSV file, reads it, and plots both runA and runB against the shared time column. Save it as a .tex file and compile it with a current LaTeX installation.
\documentclass{article}
\begin{filecontents*}{data.csv}
time,runA,runB
0,1,2
1,2.2,1.8
2,3.1,3.4
3,2.8,4.1
\end{filecontents*}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.18}
\begin{document}
\pgfplotstableread[col sep=comma]{data.csv}\datatable
\begin{tikzpicture}
\begin{axis}[
xlabel={Time},
ylabel={Value},
legend pos=north west,
grid=major,
]
\pgfplotsinvokeforeach{runA,runB}{%
\addplot+[mark=*] table[x=time,y=#1] {\datatable};
\addlegendentry{#1}
}
\end{axis}
\end{tikzpicture}
\end{document}
The filecontents* environment writes data.csv when the document is compiled. If you already have a CSV file, remove that environment and keep the \pgfplotstableread command, changing data.csv to the file’s name or path.
How the loop works
\pgfplotstableread[col sep=comma]{data.csv}\datatable loads the table and stores it in the macro \datatable. The option col sep=comma tells PGFPlots that commas separate fields. The first row supplies the column names: in this example, time, runA, and runB.
The loop receives a comma-separated list of column names:
\pgfplotsinvokeforeach{runA,runB}{...}
On the first pass, #1 is runA; on the second, it is runB. The plot command therefore behaves as if you had written these two commands individually:
\addplot+[mark=*] table[x=time,y=runA] {\datatable};
\addplot+[mark=*] table[x=time,y=runB] {\datatable};
The x=time option selects the horizontal coordinate, while y=#1 selects the current vertical-coordinate column. Both series use the same x-column. The \addlegendentry{#1} line is inside the loop, so each plot receives its own legend entry. Remove that line if you do not need a legend, or replace #1 with a descriptive label if the CSV column names are not suitable for display.
Adapting the column list
To plot different y-columns, change only the list in \pgfplotsinvokeforeach. For example, {control,treatment,reference} will generate three plots, provided those names match columns in the table. To change the x-column, edit x=time to the appropriate header, such as x=distance.
For a file with many columns, you can keep the x-column fixed and list only the columns you want to plot. You do not need to include the x-column in the loop. If you need a different label for each line, write explicit labels in the loop body or define a separate mapping between column names and legend text; #1 itself is just the current list item.
Common mistakes
- Forgetting the delimiter option: PGFPlots commonly expects whitespace-separated data by default. For a comma-separated file, set
col sep=commawhen reading the table. - Using a header that does not match: The names in
x=...andy=...must match the CSV header. Check spelling and capitalization;runAandrunaare different names. - Putting the wrong value in the loop list: The loop items must be y-column names, not row numbers or data values. Keep the shared x-column in the
x=...option. - Using decimal commas without accounting for them: In this format, commas delimit fields, so decimal values should normally use a period, such as
2.2. A file that also uses commas as decimal marks needs a different, unambiguous delimiter and matching table settings. - Expecting the loop to create legend entries automatically:
\addplotdraws a series, but a named legend entry requires\addlegendentryor another legend configuration.
If each column needs a different color or mark, PGFPlots can cycle styles automatically across successive \addplot commands. You can also set styles directly in the loop or configure the cycle list for the axis.
References
Spotted an error? Send a correction. Read how we write and check articles in our editorial policy.