Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

What I want to plot

I'd like to plot several stacked xbar plots where each bar plot contains two values. The total from each xbar-plot is based on one unit, i.e. the smallest bar represents "1" while the other are a multiple from this plot, e.g. 2 or 2.5 etc.
The two values per stacked plot are then percentages, i.e. 80% and 20%.

The problem

On the X axis I want the scale from 0 to the max value with one axis for all plots. On each stacked plot I want to plot a scale ranging from 0% to 100%. The problem is: I can either plot only the absolute value on the X-axis or have the percentages per bar plot but not a mixture.

I want to know if there is a way to set something like a local coordinate system for each bar-plot. Or any hint to set the min and max value for the scale of a bar-plot. Or, a way hoe I can multiply the ticks from the percentages by the scaling factor.

My code so far:

%% my preamble
    \documentclass[11pt, a4paper]{article}
\usepackage{pgfplots}
                \pgfplotsset{compat=1.5.1}
    \usepackage{tikz}
    \usetikzlibrary{decorations.pathreplacing, 
                            calc, 
                            matrix, 
                            positioning,
                            pgfplots.dateplot,
                            shapes.geometric,
                            shapes.misc,
                            shapes.arrows,
                            shapes.symbols
                           }

\begin{tikzpicture}
   \pgfplotsset{ 
    every linear axis/.append style = 
    {
     width = 3cm,
     font = \scriptsize, 
     %scale only axis  %% uncommenting this results scales percentage over  
                       %% absolute value: not desired
    },
    stacked/.style = 
    { 
    xbar stacked, 
    bar width   = 5pt,
    axis y line = none,
    xmin =  0, 
    xmax = 40, %% largest value, needed to set absolute max
    scale only axis  %% commenting this results in too short percentage  
                     %% scales
    },
    percent/.style = 
    {
    xmin =   1,
    ymin =   0,
    ymax =   1,
    axis y line  = none,
    axis x line* = top,
    yshift = 0.5cm,
    }
   }

    \begin{scope}[yshift = 4.75cm, xshift = 7cm]
     \begin{axis}[stacked, axis x line = none]
         \addplot coordinates { (14.45, 0) };  
         \addplot coordinates { ( 2.55, 0) };
       \end{axis}

     \begin{axis}
       [percent, xmax = 17,
        x coord trafo/.code= %% routine to transform absolute values into 
                             %% percentages
        {
         \pgfmathparse{#1 / 17 * 100}
        }]
      \end{axis}
    \end{scope} 

    %% almost the same as above. However, using the last entry to plot  
    %% absolute X-axis
    \begin{scope}[yshift = 2.5cm, xshift = 7cm]
       \begin{axis}[stacked, xmax = 40, axis x line* = bottom]
         \addplot coordinates{ (32, 0) };  
         \addplot coordinates{ ( 8, 0) };
       \end{axis}
       \begin{axis}[percent, xmax = 40,
        x coord trafo/.code=
        {
         \pgfmathparse{#1 / 40 * 100}
        }]
     \end{axis}
    \end{scope} 
share|improve this question
    
Maybe the answer to this question How to have linked axes on plots may provide some help? –  Leeser May 30 '12 at 9:26

1 Answer 1

up vote 6 down vote accepted

Instead of using a second axis environment for the secondary axis, you could make use of the extra x ticks. Here's a .code key that adds a percentage scale at the top of the plot. You don't need to supply the maximum value.

An alternative (that I would personally prefer) could be to add the percentage value to each bar segment. You can place nodes near the bars using nodes near coords, and calculate the percentages using \pgfmathparse{100*\pgfplotspointmeta/\pgfplots@axiswide@metamax}. This makes it easier to read the actual percentage value from the plot.


Code for plot with two x axes

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\makeatletter
\pgfplotsset{
    compat=1.5.1,
    percentage ticks/.style={
        before end axis/.code=\pgfplotsset{percentage ticks code}
    },
    percentage ticks code/.code={
        \pgfmathfloattofixed{\pgfplots@axiswide@metamax}
        \edef\pgfplotsaxiswidemetamax{\pgfmathresult}
        \pgfmathsetmacro\step{\pgfplotsaxiswidemetamax/4}
        \pgfplotsset{
            xtick pos=left,
            xlabel=Units,
            extra description/.code={
                \node [yshift=3ex, anchor=south] at (rel axis cs:0.5,1) {\%};
            },
            extra x ticks={0,\step,...,\pgfplotsaxiswidemetamax},
            extra x tick labels={0,25,...,100},
            extra x tick style={
                xtick pos=right,
                xticklabel pos=right
            }
        }
    }
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
    xbar stacked,
    xmin=0,
    y=1cm,
    hide y axis,
    enlargelimits=false,
    percentage ticks
]
\addplot coordinates { (14.45, 0) };  
\addplot coordinates { ( 2.55, 0) };
\end{axis}
\end{tikzpicture}
\end{document}

Code for plot with labels for each bar

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\makeatletter
\pgfplotsset{
    compat=1.5.1,
    percentage ticks/.code={
        \pgfplotsset{
            xtick pos=left,
            axis x line*=left,
            xlabel=Units,
            nodes near coords={
                \pgfkeys{
                    /pgf/fpu=true,  % PGFplots uses floating points internally
                    /pgf/fpu/output format=fixed
                }
                \pgfmathparse{100*\pgfplotspointmeta/\pgfplots@axiswide@metamax}
                \pgfmathprintnumber{\pgfmathresult}\,\%
            },
            every node near coord/.append style={yshift=1ex}
        }
    }
}
\makeatother

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    xbar stacked,
    xmin=0,
    y=0.5cm,
    hide y axis,
    percentage ticks,
    enlargelimits=false
]
\addplot coordinates { (14.45, 0) };  
\addplot coordinates { ( 2.55, 0) };
\end{axis}
\end{tikzpicture}
\end{document}
share|improve this answer
1  
sorry for the late reply and thx a lot for this solution. It works and I'll implement it in a a bigger scale as soon as possible. As mentioned, your second version is actually much nicer. –  LeJosh May 31 '12 at 15:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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