# Allow underscore in PGFPlots tick labels read from table

I'm trying to use the text data from a table column as the tick labels in a plot. The text data contains underscores, which makes LaTeX throw a Missing $inserted error. I'd usually get around this by loading the underscore package, and that works fine if I provide the list of tick labels explicitly using xticklabels={A_B,B_C}. However, when I use the xticklabels from table={<table name>}{<column name>} syntax, the underscores are not printed and I get the Missing$ error again.

I looked at what the the xticklabels from table option does, and basically it just reads the specified table column, writes the content into a list, and then unpacks that list for each tick, using the following macro:

\makeatletter
\def\pgfplots@user@ticklabel@list@x{%
\pgfplotslistselectorempty\ticknum\of\pgfplots@xticklabels\to\tick
\tick
}
\makeatother


\pgfplots@xticklabels is the list that the labels were stored into, and \tick is just a macro that holds the label text for a single tick. Using \show\tick in that macro shows that it really just holds the plain text:

> \tick=macro:
->A_B.


Now ordinarily, that should just work. If I say \def\testtext{_} and then I print that text using another macro, say \def\printtest{\testtext} \printtest, the underscore shows up.

How can I use underscores in ticklabels specified using xticklabels from table without having to replace the underscores in the data table with \_?

\documentclass{article}

\usepackage{underscore}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

%% For your convenience: This is the unaltered macro that prints
%% the tick label when "xticklabels from table" is used
\makeatletter
\def\pgfplots@user@ticklabel@list@x{%
\pgfplotslistselectorempty\ticknum\of\pgfplots@xticklabels\to\tick
\tick
}
\makeatother

Label Value_A
A_B 1
B_C 2
}\datatable

\begin{document}

\begin{tikzpicture}
\begin{axis}[
xtick=data,
% xticklabels={A_B,B_C}, % <- this works
xticklabels from table={\datatable}{Label} % <- this doesn't
]
\end{axis}
\end{tikzpicture}
\end{document}

-
In addition to your question, this sounds as if pgfplots should offer more freedom to customize the typesetting of table values. In your case, $\tick$ would do the job... hm. –  Christian Feuersänger Feb 8 '13 at 21:28
Is the fact that you load your table before \begin{document} an essential part of the request? After all, the modifications of underscore are ineffective before \begin{document}, so the table data has "raw" underscore values. If you move \pgfplotstableread after \begin{document}, everything works well. –  Christian Feuersänger Feb 9 '13 at 16:00
@ChristianFeuersänger: I tried moving the \pgfplotstableread command after \begin{document}, but I still get errors with the underscore in the column name. The underscores in the "Label" column work fine though, so that's at least a partial success. –  Jake Feb 9 '13 at 16:51
ah yes... I remember that I eliminated the underscore from the column name. The problem here is of a different nature: pgfplots expects columns names to be expandable material. The active character introduced by underscore is not expandable. –  Christian Feuersänger Feb 10 '13 at 21:04

Would you consider this as a valid answer? I cannot really test it now and it's too long for a comment. The idea is to "disable the math-mode function of _ while we read the data".

\catcode\_=12 % category other
Label Value
A_B 1
B_C 2
}\datatable
\catcode\_=8 % category subscript

-
It's working, but it replaces the underline with a point. –  Reza Feb 7 '13 at 8:35
@Reza: It comes out as an underscore if you use \usepackage[T1]{fontenc} in the preamble. –  Jake Feb 7 '13 at 8:43
@tohecz: That's a good idea, and I guess it's a nice workaround, but I'd still like to understand why the underscore package can't seem to do its magic in this context. –  Jake Feb 7 '13 at 8:44
And when I use lualatex, do I have to specify another catcode? –  Reza Feb 7 '13 at 8:47
@Jake underscore changes the catcode of _ with \AtBeginDocument –  egreg Feb 7 '13 at 9:31

Here's a patch to the table reading commands:

\documentclass{article}
\usepackage[T1]{fontenc}

\usepackage{etoolbox}
% \usepackage{underscore} % load if explicit underscores have to be used
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\makeatletter
% Patch the command that precedes reading the table
{\pgfplotstableinstallignorechars}
{\catcode\_=13 \begingroup\lccode~=_
\lowercase{\endgroup\let~}\textunderscore
\pgfplotstableinstallignorechars}
{}{}
% Patch the command that restores the category codes
{\noexpand}
{\catcode\string\noexpand\_=\the\catcode\string\_ \noexpand}
{}{}
\makeatother

%% For your convenience: This is the unaltered macro that prints
%% the tick label when "xticklabels from table" is used
\makeatletter
\def\pgfplots@user@ticklabel@list@x{%
\pgfplotslistselectorempty\ticknum\of\pgfplots@xticklabels\to\tick
\tick
}
\makeatother

Label Value
A_B 1
B_C 2
}\datatable

\begin{document}

\begin{tikzpicture}
\begin{axis}[
xtick=data,
%xticklabels={A_B,B_C}, % <- this works with package underscore
xticklabels from table={\datatable}{Label} % <- this works
]

The only way to get a real underscore independently of the output encoding is to make _ active and equivalent to \textunderscore. The example uses T1, but runs also with OT1.
@Reza I have no issue if I run the example with lualatex, either loading fontspec or not. –  egreg Feb 7 '13 at 9:28
@Jake Of course. :(` For the titles one should stringify them. There's a big deal of catcode juggling there. –  egreg Feb 7 '13 at 9:58