6

I'd like to

  • create a bar chart
  • read data directly from file,
  • add detailed description directly inside/over the bars
  • and write the actual value near the actual coord
  • set bar color according to a column

my preferred result would look like this:

That would be the dream

That's what I got so far:

That's what I got so far

\documentclass{article}
\usepackage[utf8x]{inputenc}
\usepackage{pgfplots,pgfplotstable}

\pgfplotsset{compat=1.9}
\pgfplotstableread[col sep=comma]{
surname,prename,values
Miller,Martin,0.8
Public,John,0.4
Miller,Catherine,0.6
}\testdata

\begin{document}

    \begin{tikzpicture}
        \begin{axis}[
                xbar,
                ytick = data,
                yticklabels from table={\testdata}{surname},
                major y tick style = transparent,
                ]
            \addplot table[y expr=\coordindex,x=values]{\testdata};
        \end{axis}
    \end{tikzpicture}

\end{document}
  • Consider starting the x-axis at 0.0 rather than 0.3. What you have now is visually misleading (but perhaps that's what you intend). – Ethan Bolker Jan 20 '14 at 15:28
  • I'm not sure whether I want to go for visually comparable (starting from 0) or seeing differences better (current range). Nevertheless I thought about that and it's the smallest problem (adding xmin and xmax). – hardmooth Jan 20 '14 at 15:38
  • Fair enough - thinking about it is the important part. If you go for seeing differences, you could at least show a break in the x-axis. – Ethan Bolker Jan 20 '14 at 15:47
5

You can place the descriptions of the bars using nodes near coords. By default, that will print the meta value at the end of the bar, which in turn defaults to the dependent variable (the x coordinate in this case).

To also print the prename value, several steps are required: First, you need to make the content of that column available to PGFPlots. You do this by adding point meta=explicit symbolic to the \addplot options (instructing PGFPlots to expect some kind of non-numerical auxiliary data for each data point). In the table options, you can then set meta=prename. The content of the prename column will then be available for each data point by using \pgfkeysvalueof{/pgfplots/meta}.

Then, you need to find a way to print this at the desired position. Unfortunately, nodes near coords only prints a single node. Fortunately, you can teach PGFPlots to print extra nodes by "piggybacking" onto this node by using every node near coord/.append style={append after command=node {<some text>}. This will append node {<some text>} after the label node.

In order to position this extra node correctly, you'll need to shift it. By default, it is placed at the tip of the bar. To position it at the base of the bar, you can use node [anchor=west] at (axis direction cs:-\pgfkeysvalueof{/data point/x}+\pgfkeysvalueof{/pgfplots/xmin},0). Note: The /pgfplots/xmin is only necessary if you want your bar plot to start from some value other than zero, which is not usually a good idea. As Ethan pointed out in the comments, that's usually misleading. If you want to highlight differences by decreasing the plot range, consider using points instead of bars.

You'll notice that if you do this, the content of prename column is printed twice: once at the base and once at the tip of the bar. To get the x value back, set nodes near coords=\pgfkeysvalueof{/data point/x} (instead of just nodes near coords, which is shorthand for nodes near coords=\pgfmathprintnumber{\pgfplotspointmeta}).

Here's the result of the effort:

... and here's the code:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots,pgfplotstable}

\pgfplotsset{compat=1.9}
\pgfplotstableread[col sep=comma]{
surname,prename,values
Miller,Martin,0.8
Public,John,0.4
Miller,Catherine,0.6
}\testdata

\begin{document}

    \begin{tikzpicture}
        \begin{axis}[
                    xmin=0,
                xbar,
                ytick = data,
                yticklabels from table={\testdata}{surname},
                major y tick style=transparent,
                point meta=explicit symbolic
                ]
            \addplot +[
                    nodes near coords=\pgfkeysvalueof{/data point/x},
                    every node near coord/.append style={
                        anchor=west, 
                        append after command={
                            node [anchor=west] at (axis direction cs:-\pgfkeysvalueof{/data point/x}+\pgfkeysvalueof{/pgfplots/xmin},0) {\pgfkeysvalueof{/data point/meta}}}
                    }
                ] table [y expr=\coordindex, meta=prename, x=values]{\testdata};
        \end{axis}
    \end{tikzpicture}

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.