# pgfplots using strings *from data table* as x axis labels in bar chart

I've seen some of the other threads on using strings as x axis labels, but nothing that fits my situation.

I'm trying to create a bar chart from a CSV file. I can do it so long as everything in the data is numeric. However, in my actual data table, the first row is multi-word string descriptions. I need these descriptions to be the x axis labels for each bar.

I've tried symbolic x coords, but I get the "could not parse input as a floating point number" error. I've also tried adding an ID column and using that as the x values, and assigning xtick labels as the string descriptors. I get the same issue that way.

Here's an attempt at an MWE:

\documentclass{article}

\usepackage{lmodern}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\pgfplotstabletypeset[columns/category/.style={string type},col sep=comma]{Book3.csv}
\vspace{1cm}

\begin{tikzpicture}
\begin{axis}[
ybar,
xlabel=Xstuff,
ylabel=Value,
symbolic x coords={cat a,cat b,cat c,cat d,cat e,cat f,cat g},
%xtick labels={cat a,cat b,cat c,cat d,cat e,cat f,cat g},% this is from when i tried the xtick label method
xtick=data,
nodes near coords,
nodes near coords align={vertical}]
%\addplot table[x=category,y=value]{Book3.csv};& again, from trying the xtick label method

\end{axis}

\end{tikzpicture}
\end{document}


Since I suspect this might get answered quickly by you chart gurus, I have a follow-up question:

I have to do a bunch of these charts, and I would like to automate the symbolic x coords process. Is there a way to populate the dictionary of accepted x coords by reading a column of the data? (something like symbolic x coords={columns/category/{Book3.csv}} )?

Book3.csv looks like this (ignore the ID column if using the xtick label method):

ID, category, value, value 2
1,  cat a,    1,     7
2,  cat b,    2,     6
3,  cat c,    3,     5
4,  cat d,    4,     4
5,  cat e,    5,     3
6,  cat f,    6,     2
7,  cat g,    7,     1

• When I add col sep=comma to the table options of the addplot command, your example compiles fine. Can you check whether it does for you, too? – Jake Jul 14 '12 at 21:00
• Wow, ermm.. Yeah, it definitely does. I feel silly. I'm going to make sure it works on my actual document instead of this mock-up and get back to you. – Trevor Jul 14 '12 at 21:05
• Ok yeah, I just rebuilt my actual document using my MWE and it works. Thanks for catching the 'col sep=comma' thing, Jake. I'd still like to know the second part of the question, maybe I'll eliminate the MWE and just ask the second question about populating the 'symbolic x coord' dictionary from a data table. – Trevor Jul 14 '12 at 21:12
• Hehe, glad the first problem could be solved so easily. That happens to me all the time. About the second part: I've posted a question that doesn't populate the symbolic x coords dictionary, but sets the x tick labels. I find that approach much easier to work with than the symbolic coordinates. I don't think it's possible to populate the symbolic dictionary with PGFPlots tools, it would probably require PGFPlotstable features and some expansion magic. Not sure it's worth the effort. Do you think the approach in my answer will work for you? – Jake Jul 14 '12 at 21:20

Instead of trying to populate the list of permitted symbolic coordinates, I would recommend to use the xticklabels from table key to set the labels. You don't need to provide an explicit ID column for this to work, you can just use x expr=\coordindex. As long as you also use xtick=data, the labels will always be assigned to the correct bars.

\documentclass{article}

\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}

\begin{filecontents}{testdata.csv}
category, value, value 2
cat a,    1,     7
cat b,    2,     6
cat c,    3,     5
cat d,    4,     4
cat e,    5,     3
cat f,    6,     2
cat g,    7,     1
\end{filecontents}

\makeatletter
\pgfplotsset{
/pgfplots/flexible xticklabels from table/.code n args={3}{%
\pgfplotstablegetcolumn{#2}\of{\coordinate@table}\to\pgfplots@xticklabels
\let\pgfplots@xticklabel=\pgfplots@user@ticklabel@list@x
}
}
\makeatother
\begin{document}

\begin{tikzpicture}
\begin{axis}[
ybar, ymin=0,
xlabel=Xstuff,
ylabel=Value,
flexible xticklabels from table={testdata.csv}{category}{col sep=comma},
xticklabel style={text height=1.5ex}, % To make sure the text labels are nicely aligned
xtick=data,
nodes near coords,
nodes near coords align={vertical}]

• Is it necessary to do the pgfplotstableread step first? I'm running into problems trying to use xticklabels from table={Book3.csv}{category}, – Trevor Jul 14 '12 at 21:18
• @Trevor: Yeah, unfortunately in this case you'll need to read the table first because the datafile is comma separated, and you can't pass the col sep=comma option to the xticklabels from table key. I might open a feature request for that. – Jake Jul 14 '12 at 21:21
• @Trevor: I've edited my answer to include a new key flexible xticklabels from table that takes three arguments, with the last one taking options like col sep=comma. I'll try to implement this more properly at some point, with an optional argument instead of a mandatory one, but it works for the time being. – Jake Jul 14 '12 at 21:35
• Thanks. Is there a way to read the xticklabels from table from a row of a table rather than a column? I kind of need the table transposed to make other parts of the plotting easier. – Trevor Jul 14 '12 at 21:37