我正在读取结构为外部组(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}