[Tex/LaTex] How to change the mark in a pgfplots boxplot

boxplotpgfplots

I have my own custom style for boxplots which I like very much. I like it so much I would like to use it everywhere. I used it with the old boxplots, and it did everything I wanted.

However, the style is broken with the new style of boxplots. Specifically, I like to use mark=x for my outliers, and this gets ignored by the new code.

Exploring the code of pgfplots.statistics (the library that defines the boxplot code), I realised that there is a \pgfplots@boxplot@ensure@plot@mark macro that 1) checks the value of \ifpgfplots@boxplot@ensure@plot@mark and (if true?) resets the mark (ie, mark=*).

Later, this if is assigned to a handler called boxplots/ensure mark, with a rather cryptic remark:

% mainly used for compatibility.
boxplot/ensure mark/.is if=pgfplots@boxplot@ensure@plot@mark,

Now, I like compatibility as much as the next guy, but I like my boxplot style better, and I like to live on the edge, so I'm looking for ways to revert this and damn the consequences. (Incidentally, if someone can explain to me what those consequences might be, I'd be much obliged).

I've tried doing

\makeatletter
\pgfplots@boxplot@ensure@plot@markfalse
\makeatother

in my preamble, but no go.

I've tried

\pgfplotsset{
  boxplot/ensure mark=false,
}

but that did nothing either.

The only way I can actually force my own mark, is by repeating the mark=x line after the boxplot has been called. This does work, but I want to know if there's a better solution. Specially considering there seems to be a toggle for this very task.

Here's the MWE:

\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary[pgfplots.statistics,calc]

% Tried this, didn't work
% \makeatletter
% \pgfplots@boxplot@ensure@plot@markfalse
% \makeatother

\pgfplotsset{
  compat=1.12,
  boxplot/box width/.initial=1em,
  solid boxes/.style={
    clip = false,
    solid,
    mark=x,
    boxplot/draw direction=y,
    boxplot/whisker extend=0,
    boxplot/draw/median/.code={%
      \draw[mark size=2pt,/pgfplots/boxplot/every median/.try]
        \pgfextra
        \pgftransformshift{
          \pgfplotsboxplotpointabbox
            {\pgfplotsboxplotvalue{median}}
            {0.5}
        }
        \pgfsetfillcolor{white}
        \pgfuseplotmark{*}
        \endpgfextra
      ;
    },
    boxplot/draw/box/.code={
      \draw[fill,/pgfplots/boxplot/every box/.try]
        ($(boxplot box cs:\pgfplotsboxplotvalue{lower quartile},0.5)!0.5\pgfkeysvalueof{/pgfplots/boxplot/box width}!(boxplot box cs:\pgfplotsboxplotvalue{lower quartile},0)$)
        rectangle
        ($(boxplot box cs:\pgfplotsboxplotvalue{upper quartile},0.5)!0.5\pgfkeysvalueof{/pgfplots/boxplot/box width}!(boxplot box cs:\pgfplotsboxplotvalue{upper quartile},1)$)
      ;
    }
  },
  % Tried this, didn't work
  boxplot/ensure mark/.is if=pgfplots@boxplot@ensure@plot@mark,
  boxplot/ensure mark=false,
}

\begin{document}

\begin{figure}
  \centering
  \begin{tikzpicture}
    \begin{axis}[
        xtick={1,2,3},
        xticklabels={Group A, Group B, Group C},
        % This applies the style, but the mark gets overwritten
        solid boxes,
      ]
      \addplot+[% Group A:
        boxplot prepared={
          lower whisker=42, lower quartile=45,
          median=47,
          upper quartile=47.5, upper whisker=48,
        },
      ] table[row sep=\\,y index=0] { 40\\ 34\\ 56\\ };
      \addplot+[% Group B:
        boxplot prepared={
          lower whisker=36, lower quartile=39,
          median=40,
          upper quartile=41, upper whisker=43,
        },
      ] coordinates {};
      \addplot+[% Group C:
        boxplot prepared={
          lower whisker=41, lower quartile=44,
          median=45,
          upper quartile=46, upper whisker=47,
        },
        % This works, but is not a complete solution
        mark=x,
      ] coordinates {(0,35) (0,55)};
    \end{axis}
  \end{tikzpicture}
  \caption[A caption]{A caption for my figure}
\end{figure}

\end{document}

And a picture, with helpful annotations:

The output of the MWE: a vertical boxplot with three boxes. The one on the left marks outiers with circles; the one on the right marks them with exes. The latter are labelled with a happy face.

Best Answer

Even though the question is old, I couldn't find another one solving the problem. I fiddled around a bit with the code and managed to get it to work. Specifically, I used the command

every boxplot/.style={mark=x,every mark/.append style={mark size=1.5pt}}

and it worked ;)