15

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


\pgfplotstableread{
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
        ]
     \addplot table[x expr=\coordindex]{\datatable};
    \end{axis}
  \end{tikzpicture}
\end{document}
4
  • 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. Feb 8, 2013 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. Feb 9, 2013 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, 2013 at 16:51
  • 1
    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. Feb 10, 2013 at 21:04

2 Answers 2

6

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
\pgfplotstableread{
Label Value
A_B 1
B_C 2
}\datatable
\catcode`\_=8 % category subscript
5
  • It's working, but it replaces the underline with a point.
    – Reza
    Feb 7, 2013 at 8:35
  • 1
    @Reza: It comes out as an underscore if you use \usepackage[T1]{fontenc} in the preamble.
    – Jake
    Feb 7, 2013 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, 2013 at 8:44
  • 1
    And when I use lualatex, do I have to specify another catcode?
    – Reza
    Feb 7, 2013 at 8:47
  • @Jake underscore changes the catcode of _ with \AtBeginDocument
    – egreg
    Feb 7, 2013 at 9:31
6

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
\patchcmd{\pgfplotstablereadpreparecatcodes@}
  {\pgfplotstableinstallignorechars}
  {\catcode`\_=13 \begingroup\lccode`~=`_ 
   \lowercase{\endgroup\let~}\textunderscore
   \pgfplotstableinstallignorechars}
  {}{}
% Patch the command that restores the category codes
\patchcmd{\pgfplotstablereadpreparecatcodes}
  {\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

\pgfplotstableread{
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
        ]
     \addplot table[x expr=\coordindex]{\datatable};
    \end{axis}
  \end{tikzpicture}
\end{document}

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.

enter image description here

5
  • It seems not to work with lualatex.
    – Reza
    Feb 7, 2013 at 9:24
  • @Reza I have no issue if I run the example with lualatex, either loading fontspec or not.
    – egreg
    Feb 7, 2013 at 9:28
  • It's true, I modified your example, the one you provided indeed worked well with lualatex. In my example I'm loading data from file, this seems not to work.
    – Reza
    Feb 7, 2013 at 9:45
  • @egreg: Thanks, that looks very promising. However, it introduces an error if the column names contain underscores (which works with the unpatched version). I've edited my question to include an example
    – Jake
    Feb 7, 2013 at 9:53
  • @Jake Of course. :( For the titles one should stringify them. There's a big deal of catcode juggling there.
    – egreg
    Feb 7, 2013 at 9:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .