堆叠条形图中具有相同 x 索引的条形

堆叠条形图中具有相同 x 索引的条形

我正在读取结构为外部组(x 索引/行)的数据,其中包含不同的内部类别(多列),这些类别本身又由多个值组成。目标是创建一个反映这一点的堆叠条形图,并将类别显示为一个 x 刻度下的单独条形。

类别的分离是通过相对于当前类别移动 x 值来实现的。然而,这似乎是堆叠条形图的一个问题,因为具有相同原始 x 值的连续条形图从上一个条形图结束的地方开始。 错误堆叠

在这种情况下,在不修改文件或表格的情况下,我希望它看起来像什么样子(实际文件有几十列和行):

期望结果

\documentclass[11pt]{book}
\usepackage{pgfplots}
\usetikzlibrary{patterns}
\usepackage{pgfplotstable}
\pgfplotscreateplotcyclelist{mycyclelist}{
    black,  postaction={pattern color=blue,     pattern=vertical lines}\\%
    black,  postaction={pattern color=orange,   pattern=horizontal lines}\\%
    black,  postaction={pattern color=green,    pattern=grid}\\%
    black,  postaction={pattern color=red,      pattern=north east lines}\\%
    black,  postaction={pattern color=purple,   pattern=crosshatch dots}\\%
}

\begin{document}
\begin{figure}[!htbp]
\begin{tikzpicture}
    \pgfplotstableread{
    x   As  Aa  A1  A2  A3  A4  A5  Bs  Ba  B1  B2  B3  B4  B5
    1   0   244415  0.3011  0   99.6072 0   0.0925  0   4142970 0.034   0   99.9496 0.0002  0.0162
    2   0   514279  5.4288  0   93.9848 0.0016  0.5855  0   8376969 1.7197  0   98.3238 0.0001  0.0402
    }\datatable

    \begin{axis}[
                    ybar stacked, 
                    bar width=8pt, 
                    cycle list name = mycyclelist, 
                    ymin=0, 
                    xtick=data, 
                    legend entries={1, 2, 3, 4, 5}, 
                    legend columns=5, 
            ]

        \foreach \y/\plotlabel in {0/A, 1/B} { % categories A and B
            \foreach \i in {0,...,4} { % composing values inside a category
                \edef\temp{\noexpand
                    \addplot%
                        \ifnum\i<1% label only the first plot
                        +[nodes near coords=\plotlabel]
                        \fi
                }\temp
                    plot table [
                            header = true, 
                            x expr={\thisrowno{0}*2 + \y}, 
                            y expr={\thisrowno{\the\numexpr 3 + \y * 7 + \i}}, % offset + category * sizeof(category bundle) + value-index
                        ]
                        {\datatable};
            }
        }
    \end{axis}
\end{tikzpicture}
\end{figure}
\end{document}

pgfplots 是否使用原始 x 索引而不是修改后的索引来堆叠条形图,或者我的代码有问题?

答案1

我不确定,但看起来堆叠是逐行处理的。我也不知道这是否可以自定义。我通过使用多个axis环境来规避这个问题: 示例代码的输出

\documentclass[11pt]{book}
\usepackage{pgfplots}
\usetikzlibrary{patterns}
\usepackage{pgfplotstable}
\pgfplotscreateplotcyclelist{mycyclelist}{
    black,  postaction={pattern color=blue,     pattern=vertical lines}\\%
    black,  postaction={pattern color=orange,   pattern=horizontal lines}\\%
    black,  postaction={pattern color=green,    pattern=grid}\\%
    black,  postaction={pattern color=red,      pattern=north east lines}\\%
    black,  postaction={pattern color=purple,   pattern=crosshatch dots}\\%
}
\pgfplotsset{compat=1.7}
\begin{document}
\begin{figure}[!htbp]
\begin{tikzpicture}
    \pgfplotstableread{
    x   As  Aa  A1  A2  A3  A4  A5  Bs  Ba  B1  B2  B3  B4  B5
    1   0   244415  0.3011  0   99.6072 0   0.0925  0   4142970 0.034   0   99.9496 0.0002  0.0162
    2   0   514279  5.4288  0   93.9848 0.0016  0.5855  0   8376969 1.7197  0   98.3238 0.0001  0.0402
    }\datatable
    \pgfplotstablegetrowsof{\datatable}
    \pgfmathsetmacro{\datatablerows}{\pgfplotsretval}

    % Axis limits
    \pgfmathsetmacro{\xmin}{0.5}
    \pgfmathsetmacro{\xmax}{\datatablerows + 0.5}
    \pgfmathsetmacro{\ymin}{0}
    \pgfmathsetmacro{\ymax}{120}

    % Categories
    \def\categories{0/A, 1/B}
    \pgfmathsetmacro{\ncategories}{2}

    % Width of a bar group (0 -- 1)
    \pgfmathsetmacro{\contentwidth}{0.5}

    % Gap between bars in the same group, proportional to bar width
    \pgfmathsetmacro{\innergap}{0.75}

    \pgfmathsetmacro{\barwidth}{\contentwidth /
      (\ncategories + (\ncategories-1)*\innergap)}
    \pgfmathsetmacro{\innerskip}{(\innergap + 1) * \barwidth}
    \pgfmathsetmacro{\groupstart}{-0.5*\contentwidth + 0.5*\barwidth}

    \pgfplotsset{set layers}
    % Axes and legend
    \begin{axis}[
      scale only axis,
      ybar stacked,
      bar width=1pt, 
      cycle list name = mycyclelist, 
      xmin=\xmin,xmax=\xmax,
      ymin=\ymin,ymax=\ymax,
      xtick={1,...,\datatablerows},
      ytick={0,50,100}, 
      legend entries={1, 2, 3, 4, 5}, 
      legend columns=5, 
      ]
      % Dummy bar outside visible area
      \foreach \k in {1, 2, 3, 4, 5} {
        \addplot coordinates {
          (-5, 1)
        };
      }
    \end{axis}

    \foreach \y/\plotlabel in \categories {
      % Each category gets its own axis
      \begin{axis}[
        scale only axis,
        ybar stacked, 
        bar width=\barwidth,
        cycle list name = mycyclelist, 
        xmin=\xmin,xmax=\xmax,
        ymin=\ymin,ymax=\ymax,
        axis lines=none,
        ]

        \foreach \i in {0,...,4} { % composing values inside a category
          \edef\temp{\noexpand
            \addplot%
            \ifnum\i<1% label only the first plot
            +[nodes near coords=\plotlabel]
            \fi
          }\temp
          plot table [
          header = true, 
          x expr={\thisrowno{0} + \groupstart + \y * \innerskip}, 
          y expr={\thisrowno{\the\numexpr 3 + \y * 7 + \i}},
          ]
          {\datatable};
        }
      \end{axis}
    }
\end{tikzpicture}
\end{figure}
\end{document}

相关内容