[Tex/LaTex] pgfplots using strings *from data table* as x axis labels in bar chart

bar chartlabelspgfplots

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};
%\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

Best Answer

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}

\pgfplotstableread[col sep=comma]{testdata.csv}\datatable
\makeatletter
\pgfplotsset{
    /pgfplots/flexible xticklabels from table/.code n args={3}{%
        \pgfplotstableread[#3]{#1}\coordinate@table
        \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}]
\addplot table[x expr=\coordindex,y=value]{\datatable};

\end{axis}

\end{tikzpicture}
\end{document}