我正在制作一个 pgfplots 堆叠 xbar 图,其中每个条形除了数字条形长度外,还有一个不同的标签。每对条形还有一个共同的标签。我想用其不同的标签和长度标记每个条形,并用它们的共同标签标记每对条形。
我的问题分为两个部分(编辑:(1)已回答3):
如何避免定义额外的
Score-name
列(参见下面的 MWE),而是从表中的Score
和Name
列计算它?编辑:根据包作者(回答3),没有内置对此的支持,但它在他的 TODO 列表中。编辑 2013-3-25:根据回答如下,现在已支持此功能。如何使计算的标签出现在右侧 y 轴上,而不是在条形的末尾?
我不知道描述数据的最佳方式,但是每条 extra y tick
标签,就像杰克对另一个问题可能会很好。
我不知道该怎么做每条 extra y tick
标签,但我有替代解决方案,其中标签位置不太好:在输入数据表中添加一个额外的列并将其用于每个条形标签。此解决方案的问题包括:必须添加额外的列;无法使用 pgfplots 命令从额外的列格式化标签的数字部分(如下图所示);并且(主观上)它看起来不如extra u tick
标签好看。
我的 MWE(也基于 Jake 对另一个问题。谢谢杰克!)有两张图。第一张图显示了我通过手动添加
Score-name
列得到的解决方案,第二张图显示了第一张图中数字格式指令(即科学记数法)没有得到遵守(这看起来很自然,因为Score-name
不是数字)。
\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\pgfplotsset{compat=newest}
\begin{filecontents}{data1.dat}
Age-interval Y-Position Score Name Score-name
20-30 1 0.15 Peter {0.15 (Peter)}
30-40 2 0.20 Jeff {0.20 (Jeff)}
40-50 3 0.12 Steve {0.12 (Steve)}
50-60 4 1.24 John {0.24 (John)}
\end{filecontents}
\begin{filecontents}{data2.dat}
Age-interval Y-Position Score Name Score-name
20-30 1 0.159 Peeteer {0.159 (Peeteer)}
30-40 2 0.209 Jeeff {0.209 (Jeeff)}
40-50 3 0.129 Steevee {0.129 (Steevee)}
50-60 4 1.249 Joohn {0.249 (Joohn)}
\end{filecontents}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xlabel={The \texttt{format/sci} is ignored below, but the \texttt{font=\textbackslash{}small} is obeyed below:},
xbar,
%bar width=2pt,
ytick=data,
width=8 cm,
height=6 cm,
enlarge y limits={true, value=0.2},
xmin=-0.01,
xmax = 2.0,
xticklabel pos = upper,
tick align = outside,
yticklabel pos=left,
yticklabels from table={data.dat}{Age-interval},
%ylabel={Age intervals (yr)},
nodes near coords,
every node near coord/.append style={
anchor=west,
font=\small,
% This format/sci gets ignored, because the Score-name is not a
% number:
/pgf/number format/sci,
%/pgf/number format/zerofill,
/pgf/number format/precision=2,
},
point meta=explicit symbolic
]
\addplot table [
y=Y-Position,
x=Score,
meta=Score-name
] {data1.dat};
\addplot table [
y=Y-Position,
x=Score,
meta=Score-name
] {data2.dat};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\begin{axis}[
xlabel={Both the \texttt{format/sci} and the \texttt{font=\textbackslash{}small} are obeyed below:},
xbar,
%bar width=2pt,
ytick=data,
width=8 cm,
height=6 cm,
enlarge y limits={true, value=0.2},
xmin=-0.01,
xmax = 2.0,
xticklabel pos = upper,
tick align = outside,
yticklabel pos=left,
yticklabels from table={data.dat}{Age-interval},
%ylabel={Age intervals (yr)},
nodes near coords,
every node near coord/.append style={
anchor=west,
font=\small,
% This format/sci gets ignored, because the Score-name is not a
% number:
/pgf/number format/sci,
%/pgf/number format/zerofill,
/pgf/number format/precision=2,
},
% THIS IS UNCOMMENTED ABOVE
%point meta=explicit symbolic
]
\addplot table [
y=Y-Position,
x=Score,
meta=Score-name
] {data1.dat};
\addplot table [
y=Y-Position,
x=Score,
meta=Score-name
] {data2.dat};
\end{axis}
\end{tikzpicture}
\end{document}
答案1
这是一个自定义 hack,专门针对当前问题。首先,我们nodes near coords*
根据自己的目的重新定义并删除许多必要的检查。因为我们确定我们不会使用它们。您必须将其置于 TikZ 图片环境中才能使其成为图片本地,否则所有图片都会受到影响。
然后,当将节点放置在坐标附近时,我们用(O)
此处命名的坐标固定局部范围的边界框。然后我们在局部重置该范围内的变换。这使我们能够计算到右轴的距离y
,并将west
节点稍微向左移动。
关于第一个问题,您可以使用visualization depends on=
键从其他表中收集数据,格式化数字打印等。
可能有更简单的定位方法,但我只是在自动驾驶仪上做到了。请使用它来展示更智能的方法。
完整代码如下:
\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\pgfplotsset{compat=1.7}
\usetikzlibrary{calc}
\begin{filecontents}{data1.dat}
Age-interval Y-Position Score Name
20-30 1 0.15 Peter
30-40 2 0.20 Jeff
40-50 3 0.12 Steve
50-60 4 1.24 John
\end{filecontents}
\begin{filecontents}{data2.dat}
Age-interval Y-Position Score Name
20-30 1 0.159 Peeteer
30-40 2 0.209 Jeeff
40-50 3 0.129 Steevee
50-60 4 1.249 Joohn
\end{filecontents}
\pgfkeys{/pgfplots/nodes near coords*/.append style={scatter/@post marker code/.code={%
\begin{scope}
\coordinate (O) at (0,0);
\pgftransformreset
\path let \p1 = ($(axis description cs:1,1)-(O)$) in
node[/pgfplots/every node near coord,anchor=west] at ([xshift=\x1+1.5mm]O) {#1};
\end{scope}
}
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xbar,clip=false,
ytick=data,
width=8 cm,height=6 cm,
enlarge y limits={true, value=0.2},
xmin=-0.01,xmax = 2.0,
xticklabel pos = upper,
tick align = outside,
yticklabel pos=left,
yticklabels from table={data2.dat}{Age-interval},
visualization depends on={value \thisrow{Name} \as \labela},
visualization depends on={value \thisrow{Score} \as \labelb},
every node near coord/.append style={
font=\small,
},
nodes near coords={\pgfmathprintnumber[sci]{\labelb} (\labela)},
]
\addplot table [
y=Y-Position,
x=Score,
] {data1.dat};
\addplot table [
y=Y-Position,
x=Score,
] {data2.dat};
\end{axis}
\end{tikzpicture}
\end{document}