我想制作一个堆叠的 ybar 图,每个条形上有三个堆叠的组件,每个组件垂直分为三个百分比组件(这些组件的总宽度保持不变:100%)。该图的一个条形可以用以下矩阵描述:
23 30% 50% 20%
55 10% 40% 50%
32 60% 30% 10%
这意味着条形图的第一部分(底部)高度为 32,垂直方向分为三部分,相对宽度为 60:30:10(因此三条不同宽度的窄线彼此相邻且相接)。第二部分(中间部分)高度为 55,添加在高度为 32 的第一条条形图的顶部,分为三部分,相对宽度为 10:40:50。第三部分(顶部)高度为 23,分为三部分,相对宽度为 30:50:20。
(输入格式并不重要,翻转数字或将矩阵分成两个或多个并不重要——重要的部分是获得所描述的情节。)
有人对如何实现这一目标有什么建议吗?
编辑:澄清:
上面的例子和表格仅仅描述了其中一个条形图。
另一种描述方式是制作一个 ybar 图,其中每个 ybar 都是一个马赛克图表或 Marimekko 图表,以便每个条形图都包含 Jake 在下面答案中呈现的图表类型。
答案1
这种图表类型称为马赛克图或Marimekko 图表。对此类图表有深刻的批评,请访问垃圾图表指出了一些必须注意的缺点。
尽管如此,它们可以在 PGFPlots 中相对轻松地创建,在您的情况下,通过结合xbar interval
。stack dir=x
允许xbar interval
根据值创建具有不同厚度的水平条y
。 为了使其工作,您需要在表中添加一个虚拟数据行,并且需要累积值y
,否则条形图会重叠。 您可以create on use
使用表达式来执行此操作pgfplotstable
。xbar interval
需要提供给各个图,而不是轴,否则条形图的不同部分会相对彼此偏移。
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotstableread{
23 30 50 20
55 10 40 50
32 60 30 10
0 0 0 0
}\datatable
\pgfplotstableset{
create on use/accumy/.style={
create col/expr={\prevrow{0}+\pgfmathaccuma}
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
stack plots=x,
enlargelimits=false,
table/y=accumy]
\addplot [fill=orange!60,xbar interval] table [x index=1] {\datatable};
\addplot [fill=cyan!50,xbar interval] table [x index=2] {\datatable};
\addplot [fill=yellow!50,xbar interval] table [x index=3] {\datatable};
\end{axis}
\end{tikzpicture}
\end{document}
要创建由多个此类图表组成的图表,我认为最好的办法是使用彼此相对定位的单独环境。在一个环境中axis
不可能有多个独立的stack
图表。axis
在我看来,结果看起来很漂亮,但对于传递数据来说不是很有用=)
。
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotstableread{
23 30 50 20
55 10 40 50
32 60 30 10
0 0 0 0
}\datatableA
\pgfplotstableread{
11 10 50 40
20 30 20 50
60 30 50 20
0 0 0 0
}\datatableB
\pgfplotstableread{
33 30 50 20
55 10 40 50
32 60 30 10
0 0 0 0
}\datatableC
\pgfplotstableset{
create on use/accumy/.style={
create col/expr={\prevrow{0}+\pgfmathaccuma}
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
width=3cm, y=0.03cm,
name=main axis,
hide x axis,
stack plots=x,
enlargelimits=false,
table/y=accumy]
\addplot [fill=orange!60,xbar interval] table [x index=1] {\datatableA};
\addplot [fill=cyan!50,xbar interval] table [x index=2] {\datatableA};
\addplot [fill=yellow!50,xbar interval] table [x index=3] {\datatableA};
\end{axis}
\begin{axis}[
name=second axis,
at=(main axis.south east), anchor=south west, xshift=1ex,
width=3cm, y=0.03cm, hide axis,
stack plots=x,
enlargelimits=false,
table/y=accumy]
\addplot [fill=orange!60,xbar interval] table [x index=1] {\datatableB};
\addplot [fill=cyan!50,xbar interval] table [x index=2] {\datatableB};
\addplot [fill=yellow!50,xbar interval] table [x index=3] {\datatableB};
\end{axis}
\begin{axis}[
at=(second axis.south east), anchor=south west, xshift=1ex,
width=3cm, y=0.03cm, hide axis,
stack plots=x,
enlargelimits=false,
table/y=accumy]
\addplot [fill=orange!60,xbar interval] table [x index=1] {\datatableC};
\addplot [fill=cyan!50,xbar interval] table [x index=2] {\datatableC};
\addplot [fill=yellow!50,xbar interval] table [x index=3] {\datatableC};
\end{axis}
\end{tikzpicture}
\end{document}