我试图堆叠一个组图,或者将堆叠的图分组?但是我试图得到类似这样的结果:
这个ybar stacked
选项在这里效果很好。但是当我尝试将其调整为组图时,我遇到了一些问题。目标是创建三个组,每个组都有一个xlabel
。在每个组中,每个条形图也应该有自己的xticklabel
。到目前为止,MWE 给出了这个
为什么前三个堆叠部分之后会有分离?我如何才能分别标记条形图,同时标记组?
这个groupplot
命令是否是解决这个“问题”的正确命令?
梅威瑟:
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\usetikzlibrary{pgfplots.groupplots}
\pgfplotsset{width=0.3\textwidth,compat=newest}
\pgfplotstableread{
cr Fii Faa Foo
abc 10 20 30
def 5 5 5
ghi 7 7 7
jkl 1.5 1.5 2.5
mno 2 2 2
pqrs 0 0 8
tuv 0 0 1.16
wxyz 0 5 0
}\first
\pgfplotstableread{
cr Fii Faa Foo
abc 7 7 12.9
def 7.5 7.5 7.5
ghi 8 8 8
jkl 1.5 1.5 2.25
mno 2 2 2
pqrs 0 0 8
tuv 0 0 1.544
wxyz 0 6.3 0
}\second
\pgfplotstableread{
cr Fii Faa Foo
abc 7 7 19
def 7.5 7.5 7.5
ghi 9 9 9
jkl 1.5 1.5 2.25
mno 2 2 2
pqrs 0 0 8
tuv 0 0 23
wxyz 0 8.4 0
}\third
\pgfplotsset{
select row/.style={
x filter/.code={\ifnum\coordindex=#1\else\def\pgfmathresult{}\fi}
}
}
\begin{document}
\begin{figure}[hbt!]
\centering
\begin{tikzpicture}
\begin{groupplot}
[
group style=
{columns=3,
ylabels at=edge left,
group name=plots},
ybar stacked,
scale only axis,
ylabel=y-axis,
ymin=0,
ymax=150,
height=0.5\textwidth,
xtick=\empty,
legend columns=-1,
legend image code/.code={%
\draw[#1] (0cm,-0.1cm) rectangle (0.3cm,0.1cm);
}
]
\nextgroupplot[xlabel=Item 1, legend to name=grouplegend,]
\pgfplotsinvokeforeach {0,...,7}{
\addplot table [x expr=\coordindex, select row=#1, y=Fii] {\first};
\addplot table [x expr=\coordindex, select row=#1, y=Faa] {\first};
\addplot table [x expr=\coordindex, select row=#1, y=Foo] {\first};
\addlegendentry {\pgfplotstablegetelem{#1}{cr}\of \first \pgfplotsretval}
}
\nextgroupplot[xlabel=Item 2]
\pgfplotsinvokeforeach {0,...,7}{
\addplot table [x expr=\coordindex, select row=#1, y=Fii] {\second};
\addplot table [x expr=\coordindex, select row=#1, y=Faa] {\second};
\addplot table [x expr=\coordindex, select row=#1, y=Foo] {\second};
}
\nextgroupplot[xlabel=Item 3]
\pgfplotsinvokeforeach {0,...,7}{
\addplot table [x expr=\coordindex, select row=#1, y=Fii] {\third};
\addplot table [x expr=\coordindex, select row=#1, y=Faa] {\third};
\addplot table [x expr=\coordindex, select row=#1, y=Foo] {\third};
}
\end{groupplot}
\node at (plots c2r1.north) [inner sep=0pt,anchor=south,yshift=3ex] {\ref{grouplegend}};
\end{tikzpicture}
\end{figure}
\end{document}
答案1
我认为这是一个有趣的情节。所以我将提供我的答案。
回答您的一些问题:
groupplot 命令是否是解决这个“问题”的正确命令?
是的,这样groupplot
做只是让它们以一种更简单的方式并排放置。不多也不少。每个都\nextgroupplot
实际上与封闭环境相同axis
。为什么前三个堆叠部分之后会有分离?
因为您有x expr=\coordindex
。这意味着在第二个循环中,\pgfplotsinvokeforeach
在x expr=1
第三个循环中x expr=2
。这意味着一个新列。如果您尝试注释掉ymax=80000
,您就会明白我的意思。我怎样才能分别标记各个条形图,并将其中三个条形图标记到一个站点?
我不太明白您的问题,但我认为我的答案对此有一个解决方案,否则请回复。
如何让它工作
首先,你的数据应该重新排列。你的X坐标应在第一列,然后每个站点(美国广播公司,定义,...) 应为一个新列。
这样您就可以更轻松地处理数据,而无需使用那些烦人的过滤器(如果您可以在没有过滤器的情况下工作,通常会更容易)。
因此您的数据必须采用以下格式:
\pgfplotstableread{
Criterion abc def ghi jkl mno pqrs tuv wxyz
Komp 7000 7500 7500 1500 2000 0 0 0
Komp+PV 7000 7500 7500 1500 2000 0 0 5000
Sorp 12000 7500 7500 2250 2000 8000 11600 0
}\Rapperswil
完成后你需要告诉pgfplots
使用标准列X-tickmarks。这需要使用键:xticklabels from table={\Rapperswil}{Criterion}
和xtick=data
。因此,您不需要预先输入X-数据!
最终结果变成:
\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\pgfplotstableread{
Criterion abc def ghi jkl mno pqrs tuv wxyz
Komp 7000 7500 7500 1500 2000 0 0 0
Komp+PV 7000 7500 7500 1500 2000 0 0 5000
Sorp 12000 7500 7500 2250 2000 8000 11600 0
}\Rapperswil
\begin{document}
\begin{tikzpicture}
\begin{axis}[ybar=0pt,
ybar stacked,bar shift=0pt,
xticklabels from table={\Rapperswil}{Criterion},
xtick=data,
legend style={at={(1.025,1.0)},anchor=north west},
xlabel=Rapperswil]
\pgfplotstableforeachcolumn\Rapperswil\as\col{%
\ifnum\pgfplotstablecol=0
\else
\edef\tmp{%
\noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Rapperswil};
\noexpand\addlegendentry {\col}%
}%
\tmp
\fi
}
\end{axis}
\end{tikzpicture}
\end{document}
请注意,您需要\edef
由于\pgfplotstableforeachcolumn
在循环退出时未完全展开而导致的。
群图
当您需要将其与 放在一起时,groupplots
您的代码是正确的,但是请使用y descriptions at=edge left
而不是ylabels at=edge left
。前者会在 上同时制作标签和勾选edge left
。而后者仅适用于ylabels
。
使用的示例groupplots
是执行以下操作。如果不确定该键的作用,请查阅手册。我添加了第二个表格。我将把它保留为简单的练习添加最后一个!
\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\usetikzlibrary{pgfplots.groupplots}
\pgfplotstableread{
Criterion abc def ghi jkl mno pqrs tuv wxyz
Komp 7000 7500 7500 1500 2000 0 0 0
Komp+PV 7000 7500 7500 1500 2000 0 0 5000
Sorp 12000 7500 7500 2250 2000 8000 11600 0
}\Rapperswil
\pgfplotstableread{
Criterion abc def ghi jkl mno pqrs tuv wxyz
Komp 7000 7500 8000 1500 2000 0 0 0
Komp+PV 7000 7500 8000 1500 2000 0 0 6300
Sorp 12900 7500 8000 2250 2000 8000 15440 0
}\Palermo
\begin{document}
\begin{tikzpicture}
\begin{groupplot}[group style= {
columns=2,xlabels at=edge bottom,
y descriptions at=edge left,
horizontal sep=0cm,group name=plots,
},
ymin=0,ymax=6e4,enlarge x limits={abs=.5},
ybar,ybar stacked,
/pgf/bar shift=0pt,/pgf/bar width=1.5cm,
xlabel style={yshift=-2ex}, % make the xlabel further down from the ticks
xticklabels from table={\Rapperswil}{Criterion}, % use the ticklabels from the table as a tick mark
xtick=data,legend columns=1]
% This defines a new axis environment which will be filled with data from table \Rapperswil
\nextgroupplot[xlabel=Rapperswil,legend to name=grouplegend]
\pgfplotstableforeachcolumn\Rapperswil\as\col{%
\ifnum\pgfplotstablecol=0 % The first column is "Criterion" we do not need that one, skip
\else
\edef\tmp{%
\noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Rapperswil};
\noexpand\addlegendentry {\col}%
}%
\tmp
\fi
}
% This defines a new axis environment which will be filled with data from table \Palermo
\nextgroupplot[xlabel=Palermo]
\pgfplotstableforeachcolumn\Palermo\as\col{%
\ifnum\pgfplotstablecol=0
\else
\edef\tmp{%
\noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Palermo};
}%
\tmp
\fi
}
\end{groupplot}
% Draw the dashed lines below the plot
\draw[dashed] (plots c1r1.south west) -- ++(0,-1.5);
\draw[dashed] (plots c2r1.south west) -- ++(0,-1.5);
\draw[dashed] (plots c2r1.south east) -- ++(0,-1.5);
% This will make the legend at the right of the plot just like Excel
\node at (plots c2r1.east) [inner sep=0pt,anchor=west, xshift=.6cm] {\ref{grouplegend}};
\end{tikzpicture}
\end{document}