pgfplots:堆叠 ybar 中的百分比和最终值

pgfplots:堆叠 ybar 中的百分比和最终值

我对该pgfplots软件包有两个问题。我已附上我编写的源代码。有两个功能我无法实现:

  1. 我想将总值(整个堆叠条形图的总和)放在条形图的顶部,并旋转90°。对我来说,目前只能使用命令来获取堆叠条形图每个部分的值nodes near coords

  2. 此外,堆积条形图的每个部分相对于整个堆积条形图的百分比也应显示在条形图中,并旋转90°(加法等于100%

如果可能的话,百分比应该只有一个有效数字,并且下面的数字5%不应该显示在栏中。我知道这是一个相当复杂的例子,但也许有人可以解决它。

\documentclass{article}
 \usepackage{pgfplots,pgfplotstable}
  \usetikzlibrary{pgfplots.groupplots}
   \pgfplotsset{compat=1.8}

 \pgfplotstableread{
 Criterion  ddd     ccc     vvv 
 (0)    700         750         750 
 (a)    700         750         750 
 (b)        1200        750         750     
 (c)    33      345     345
 (d)    34      333     345
 (e)    234     344     344
  }\Rob

 \pgfplotstableread{
 Criterion  ddd     ccc     vvv 
 0      70          75          75  
 a      70          75          75  
 b          120         75      75      
 c      3       34      34
 d      3       33      34
 e      23      34      34
 }\Gab


\begin{document}
 \begin{tikzpicture}
\begin{groupplot}[group style= {
    columns=2,xlabels at=edge bottom,
    ylabels at=edge left,
    horizontal sep=1cm,group name=plots,
},
ymin=0, enlarge x limits={abs=.5}, enlarge y limits={upper,value=0.4}, 
ylabel=Mon, ylabel style={text height=0.02\textwidth,inner ysep=0pt}, 
ybar,ybar stacked,
major x tick style = transparent, 
/pgf/bar shift=0pt, /pgf/bar width=9pt,
x tick label style={text height=2ex},   
xlabel style={yshift=-2ex}, 
xticklabels from table={\Rob}{Criterion}, 
xtick=data,legend columns=-1, legend style={draw=none, /tikz/every even column/.append   style={column sep=5pt}}]

\nextgroupplot[xlabel=Rob, xlabel shift = -7.5cm, legend to name=grouplegend]
\pgfplotstableforeachcolumn\Rob\as\col{
    \ifnum\pgfplotstablecol=0 
    \else
      \edef\tmp{
        \noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Rob};
        \noexpand\addlegendentry {\col}
    }
    \tmp
    \fi
}

\nextgroupplot[xlabel=Gab, xlabel shift = -7.5cm]
\pgfplotstableforeachcolumn\Gab\as\col{
    \ifnum\pgfplotstablecol=0 
    \else
    \edef\tmp{
        \noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Gab};
    }
    \tmp
    \fi

 }
  \end{groupplot}
 \draw[dashed] (plots c1r1.south west) -- ++(0,-1.5);
  \draw[dashed] (plots c1r1.south east) -- ++(0,-1.5);
 \draw[dashed] (plots c2r1.south west) -- ++(0,-1.5);
 \draw[dashed] (plots c2r1.south east) -- ++(0,-1.5);
 \node at (plots c1r1.south) [inner sep=0pt,anchor=north, yshift=-12ex]     {\ref{grouplegend}};
 \end{tikzpicture}
 \end{document}

答案1

这是一个无需 即可实现的解决方案visualization depends on

请注意,我已将给定的代码截断为只有一个图,因为第二个图中没有任何新内容,只会使代码更长。我还删除了很多样式等,这些样式几乎没有改变输出,并且与问题无关,因此也只会“打扰”或分散注意力。

(我也没有应用“只显示一个有效数字”的要求——我认为 OP 的意思是“一个小数位”——因为这看起来不太好。但我认为,如果真的有必要的话,使用给定的解决方案应该很容易适应它。)

有关解决方案如何运作的详细信息,请查看代码中的注释。

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
    \usetikzlibrary{
        pgfplots.groupplots,
    }
    \pgfplotsset{
        % so that the new feature of centering the `nodes near coords' text is applied
        compat=1.9,
        %
        % create a style which will be used to show the sum values
        % (borrowed from <http://tex.stackexchange.com/a/162389/95441>)
        show sum on top/.style={
            /pgfplots/scatter/@post marker code/.append code={
                \node [
                    black,
                    rotate=90,
                    anchor=west,
                    at={(normalized axis cs:
                            \pgfkeysvalueof{/data point/x},
                            \pgfkeysvalueof{/data point/y})
                    },
                ] {\pgfmathprintnumber{\pgfkeysvalueof{/data point/y}}};
            },
        },
    }
    \pgfplotstableread{
        Criterion   ddd     ccc     vvv
        (0)         700     750     750
        (a)         700     750     750
        (b)         1200    750     750
        (c)         33      345     345
        (d)         34      333     345
        (e)         234     344     344
    }\Rob
    % get number of columns in the table
    \pgfplotstablegetcolsof{\Rob}
        \pgfmathtruncatemacro{\NoOfCols}{\pgfmathresult - 1}
    % we also need this value again on a "zero basis" for a style
        \pgfmathtruncatemacro{\NoOfColsZeroBased}{\NoOfCols-1}
    % add column of the sum of the values in each row
    % (because you did the rest also with loops, so here is the loop solution for it)
    % (inspired by <http://tex.stackexchange.com/a/281436/95441>)
    \pgfplotstablecreatecol[
        create col/assign/.code={
                % create and initialize a variable that stores the sum values
                \pgfmathsetmacro\RowSum{0}
            % cycle through the columns
            \pgfplotsforeachungrouped \i in {1,...,\NoOfCols} {
                \pgfmathsetmacro\RowSum{\RowSum+\thisrowno{\i}}
            }
            % set the calculated value to the corresponding cell
            \pgfkeyslet{/pgfplots/table/create col/next content}{\RowSum}
        }
    ]{Sum}{\Rob}
\begin{document}
    \begin{tikzpicture}
        \begin{groupplot}[
            group style={
                columns=2,
                xlabels at=edge bottom,
                ylabels at=edge left,
                horizontal sep=1cm,
                group name=plots,
            },
            ymin=0,
            enlarge y limits={upper,value=0.4},
            ylabel=Mon,
            ybar stacked,
            % instead of making the ticks invisible, just set the length to zero
            major tick length=0pt,
            xtick=data,
            xticklabels from table={\Rob}{Criterion},
            legend columns=-1,
            % -----
            % define the number style for the `nodes near coords' where
            % only values greater than 5 should be shown
            % (adapted from <http://tex.stackexchange.com/a/59961/95441>
            nodes near coords={
                \pgfkeys{/pgf/fpu=true}
                \pgfmathparse{\pgfplotspointmeta-5}
                \pgfmathfloatifflags{\pgfmathresult}{+}{%
                    \pgfmathprintnumber[
                        precision=0,
                    ]{\pgfplotspointmeta}\%
                }{}
                \pgfkeys{/pgf/fpu=false}
            },
%            % because rotating the values would cause them to overlap
%            % I just provide the solution to that in commented form
%            nodes near coords style={
%                rotate=90,
%                font=\footnotesize,
%            },
            % to the last plot the sum value should be added as a node
            % for which we use the created style
            every axis plot no \NoOfColsZeroBased/.append style={
                show sum on top,
            },
        ]
        \nextgroupplot[
            % instead of shifting the `xlabel' just provide a title
            title=Rob,
            legend to name=grouplegend,
        ]
            % add all data columns to the axis
            \foreach \i in {1,...,\NoOfCols} {
                \addplot+ [
                    % this has to be given because we want to use a different
                    % value than the default `y' value
                    point meta=explicit,
                ] table [
                    x expr=\coordindex,
                    y index=\i,
                    % here we calculate the number which we want to be plotted
                    meta expr=\thisrowno{\i}/\thisrow{Sum}*100,
                ] {\Rob};
                        % extract the corresponding column header name from the table
                        \pgfplotstablegetcolumnnamebyindex{\i}\of{\Rob}\to{\colname}
                    % use it as legend entry
                    \addlegendentryexpanded{\colname}
            }
%        % I removed the second plot because there is nothing different here
%        \nextgroupplot
        \end{groupplot}

        \draw [dashed] (plots c1r1.south west) -- ++(0,-1.5);
        \draw [dashed] (plots c1r1.south east) -- ++(0,-1.5);

        \node [inner sep=0pt,anchor=north, yshift=-12ex]
            at (plots c1r1.south) {\ref{grouplegend}};

    \end{tikzpicture}
\end{document}

该图显示了上述代码的结果

相关内容