8

I'm using scatter/classes to define color and markers for a plot, and I would like to specify the error bar color this way as well (to match the marker color). I have seen the error bar colors in scatter plot post, but I don't know how to use the scatter class color, rather than the mapped color. Specifying the error bar color in the scatter/classes does not work.

\documentclass[article]{standalone}               
\usepackage{graphicx}
\usepackage{pgf,tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.7}

\begin{document}
\begin{tikzpicture}
    \begin{axis}
      \addplot [scatter,
        only marks,
        scatter src=explicit symbolic,
        scatter/classes={
          A0={mark=o,red,/pgfplots/error bars/.cd,
            error mark options={draw=red}},
          A1={mark=square,blue}},
        error bars/.cd,
        y dir=both,
        y explicit] 
      table[x=x,y=y,y error=err,meta=class,row sep=crcr] {
        x y err class\\
        0 0 1   A0\\
        1 1 1   A0\\
        2 0 1   A1\\
        3 2 2   A1\\
      };
    \end{axis}
\end{tikzpicture}
\end{document}

Error bars do not match scatter class

Moriambar
  • 11,466
Rinchen
  • 521
  • Possibly helpful comment on page 83 of the pgfplots manual: "Attention: The keys every mark and mark options have no effect when used inside of ! So, instead of assigning mark options, you can simply provide the options directly. They apply only to markers anyway." – John Wickerson May 09 '13 at 09:02
  • @John Wickerson - yes, I saw that in the manual. It is unclear to me how I would apply the option "directly" in this case. I'm assuming that some sort of pre- or post- processing will be necessary (unless I have missed something very obvious). – Rinchen May 09 '13 at 10:52

1 Answers1

2

One way to do this is to use the scatter/@pre marker code to "manually" draw the error bars and markers. This will automatically use the drawing style of the plot markers (including the color). A drawback is that PGFPlots doesn't adjust the axis limits automatically to accommodate the error bars. To work around this, you can also draw "conventional" but transparent error bars.

Here's a style error bars with color that takes the name of the column containing the error values as a mandatory argument, and implements the above approach. The style must be used after your scatter/classes definition, as it would otherwise be overridden.

error bars with color/.style={
    visualization depends on=\thisrow{#1} \as \error,
    visualization depends on=y \as \y,
    scatter/@pre marker code/.append code={ % Homebrew color bars
            \draw (0,0) -- +(axis direction cs:0,-\error) -- +(axis direction cs:0,\error);
            \draw (0,0) plot [mark=-] coordinates {(axis direction cs:0,\error) (axis direction cs:0,-\error)};
    },
    error bars/.cd, % Invisible color bars, to get the right axis limits
            y dir=both,
            y explicit,
            error bar style={opacity=0},
    /pgfplots/.cd
}

Full code:

\documentclass[border=5mm]{standalone}     
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.7}


\pgfplotsset{
    error bars with color/.style={
        visualization depends on=\thisrow{#1} \as \error,
        visualization depends on=y \as \y,
        scatter/@pre marker code/.append code={ % Homebrew color bars
                \draw (0,0) -- +(axis direction cs:0,-\error) -- +(axis direction cs:0,\error);
                \draw (0,0) plot [mark=-] coordinates {(axis direction cs:0,\error) (axis direction cs:0,-\error)};
        },
        error bars/.cd, % Invisible color bars, to get the right axis limits
                y dir=both,
                y explicit,
                error bar style={opacity=0},
        /pgfplots/.cd
    }
}

\begin{document}
\begin{tikzpicture}
    \begin{axis}
      \addplot [scatter,
        only marks,
        scatter src=explicit symbolic,
        scatter/classes={
          A0={mark=o,red,
          },
          A1={mark=square,blue}
        },
        error bars with color=err
         ] 
      table[x=x,y=y,y error=err,meta=class,row sep=crcr] {
        x y err class\\
        0 0 1   A0\\
        1 1 1   A0\\
        2 0 1   A1\\
        3 2 2   A1\\
      };
    \end{axis}
\end{tikzpicture}
\end{document}
David Carlisle
  • 757,742
Jake
  • 232,450
  • Jake, is there no way to pass a colour to the draw error bar/.code? The default code is documented on p. 234 of the manual, and if you add a colour to the \draw command there, you can make the bars a different colour. But I don't understand enough of how passing keys works to pass a different colour based on the marker colour. Perhaps you do, though? – Alan Munn May 11 '13 at 02:18
  • 1
    @AlanMunn: You can adjust the draw error bar code to accept different colours, but the problem is that the "real" error bars are drawn per plot, not per data point, so it's really hard to draw different error bars within the same \addplot command with different colors. It would be really nice to have that feature, but that would require a lot of digging through the PGFPlots code. Might be worth opening a feature request for that, though. – Jake May 11 '13 at 02:58
  • I see. That's too bad then. – Alan Munn May 11 '13 at 03:16
  • 2
    ... actually, "real" error bars are drawn per data point, and modifications of the color are possible. Unfortunately, error bars have no access to the value of point meta. They do not even know the coordinate index AFAIK. Fixing that would allow to insert simple commands which install the scatter/classes styles. That would be a feature request in order to improve \pgfplots@streamerrorbar@recordto. Once that is done, redefinitions of draw error bar/.code would be useful. – Christian Feuersänger May 11 '13 at 10:34
  • @ChristianFeuersänger Is there a way for me to make this a formal feature request? – Rinchen May 11 '13 at 22:54
  • @Jake Unfortunately, this solution doesn't work if the table is referenced from an outside file. I'm getting the error Package PGF Math Error: Unknown functionthisrow_unavailable_load_table_dire ctly' (in 'thisrow_unavailable_load_table_directly ').It looks like thevisualization depends on=\thisrow{#1} \as \error` line is responsible. – Rinchen May 11 '13 at 23:02
  • @ackey: I think you're trying to use a table that you read using \pgfplotstableread, right? It should work if you use the filename itself in the \addplot table command. – Jake May 12 '13 at 04:10
  • @Jake Ok, I have it working for the external table (and filtering x coords), but it doesn't seem to work for semilogyaxis (I realize that I didn't specify that in the original question). I'm not getting error messages, but the error bars are too big (and go off the plot). I made sure to change the y errors to not overlap with 0. Do you know if the axis direction draw command needs to be modified to work on a log axis? – Rinchen May 12 '13 at 08:04
  • @ackey this here is sufficient; I made an entry on my todo list. Cannot give an ETA, though – Christian Feuersänger May 12 '13 at 10:51
  • 1
    @ackey forget my last remark; I have added the missing support to the developer version of pgfplots and I verified that the error bar processing can be altered as requested. I may need to fine-tune the fix a little bit, but it appears to be ok. Please contact me by mail if you need immediate support (i.e. a patched version). – Christian Feuersänger May 12 '13 at 13:14
  • @Jake: I tried to add x errors too. So far I failed. How can I do this? –  Sep 13 '13 at 09:58