![将来自不同来源的条形图与每个 xlabel 对齐](https://linux22.com/image/292019/%E5%B0%86%E6%9D%A5%E8%87%AA%E4%B8%8D%E5%90%8C%E6%9D%A5%E6%BA%90%E7%9A%84%E6%9D%A1%E5%BD%A2%E5%9B%BE%E4%B8%8E%E6%AF%8F%E4%B8%AA%20xlabel%20%E5%AF%B9%E9%BD%90.png)
我有一个 pgfplot,它从两个文件中读取数据。我想要一个条形图,其中一个文件的值(条形)出现在一个 xlabel 上,另一个文件的值出现在另一个 xlabel 上(本例中为 A 和 B)。我当前的解决方案相当接近,但 1) 有点黑客,因为它排列循环列表中的条目,以便图表正确对齐;2) 没有将条形与 xticks 正确对齐。
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{
cycle1/.style={green},
cycle2/.style={orange},
cycle3/.style={blue},
cycle4/.style={purple},
}
\pgfplotscreateplotcyclelist{mycyclelist}{
cycle1\\%
cycle1\\%
cycle2\\%
cycle2\\%
cycle3\\%
cycle3\\%
cycle4\\%
cycle4\\%
}
\begin{document}
\pgfplotstableread{
123 11778.83 18995.27 19049.38 22236.73
}\dataA
\pgfplotstableread{
123 1925.39 7014.29 10721.35 24199.01
}\dataB
\begin{tikzpicture}
\begin{axis}[
ybar=-1pt,
bar width=5,
ymin=0,
cycle list name = mycyclelist,
xtick={0, 1},
xticklabels = {
A, B
},
enlarge x limits={abs=0.75},
]
\foreach \y in {1, 2, 3, 4} {
\addplot plot table [x expr=0, col sep=semicolon, header = true, y expr=\thisrowno{\y} / 1000]
\dataA;
\addplot plot table [x expr=1, col sep=semicolon, header = true, y expr=\thisrowno{\y} / 1000]
\dataB;
}
\end{axis}
\end{tikzpicture}
\end{document}
我正在寻找一种能够将条形图与 xticks 正确对齐的解决方案(如果可以解决循环列表技巧就更好了)。
目标可能是这样的:
而在 MWE 中,A 条稍微向左移动,B 条稍微向右移动:
答案1
图的偏移取决于图索引。forget plot
对图使用选项\dataA
不增加它们的图索引。然后它们将使用与以下图相同的循环列表条目,并且和的\dataB
偏移将相等。A
B
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotsset{
cycle1/.style={green},
cycle2/.style={orange},
cycle3/.style={blue},
cycle4/.style={purple},
}
\pgfplotscreateplotcyclelist{mycyclelist}{
cycle1\\%
cycle2\\%
cycle3\\%
cycle4\\%
}
\begin{document}
\pgfplotstableread{
123 11778.83 18995.27 19049.38 22236.73
}\dataA
\pgfplotstableread{
123 1925.39 7014.29 10721.35 24199.01
}\dataB
\begin{tikzpicture}
\begin{axis}[
ybar=3pt,% should be >0pt
bar width=6pt,
ymin=0,
cycle list name = mycyclelist,
xtick={0,1},
xticklabels = {A,B},
enlarge x limits={abs=0.75},
]
\foreach \y in {1, 2, 3, 4}{
\addplot plot table [x expr=0, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000,
forget plot% prevents increase of the plot index
]\dataA;
\addplot plot table [x expr=1, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000]\dataB;}
\end{axis}
\end{tikzpicture}
\end{document}
可以添加图例。为了将其放置在图之外,我使用
legend style={legend pos={outer north east}},
作为附加轴选项。然后我\legend{...}
在 foreach 循环后插入:
\foreach \y in {1, 2, 3, 4}{
\addplot plot table [x expr=0, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000,
forget plot% prevents increase of the plot index
]\dataA;
\addplot plot table [x expr=1, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000]\dataB;}
\legend{green,orange,blue,purple}
或者如果您想要A
和有不同的条目B
:
\foreach \y in {1, 2, 3, 4}{
\addplot plot table [x expr=0, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000,
forget plot% prevents increase of the plot index
]\dataA;
\addplot plot table [x expr=1, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000]\dataB;
\addlegendimage{empty legend}% empty legend image
}
\legend{A gr,B gr,A or,B or,A bl,B bl,A pu,B pu}
第二版本
您可以将两个图绘制在彼此的上方:
\documentclass[border=5mm,convert=false]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\pgfplotsset{
cycle1/.style={green},
cycle2/.style={orange},
cycle3/.style={blue},
cycle4/.style={purple},
}
\pgfplotscreateplotcyclelist{mycyclelist}{
cycle1\\%
cycle2\\%
cycle3\\%
cycle4\\%
}
\begin{document}
\pgfplotstableread{
123 11778.83 18995.27 19049.38 22236.73
}\dataA
\pgfplotstableread{
123 1925.39 7014.29 10721.35 24199.01
}\dataB
\begin{tikzpicture}
\pgfplotsset{%
every axis/.style={
ybar=3pt,
bar width=6pt,
cycle list name=mycyclelist,
ymin=0,ymax=25,
xmin=0,xmax=1,
enlarge x limits={abs=0.75},
enlarge y limits={upper=0.1},
}
}
\begin{axis}[
xtick={0,1},
xticklabels = {A,B},
legend style={legend pos=north west}
]
\addlegendimage{empty legend}
\foreach \y in {1,...,4}{
\addplot plot table [x expr=0, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000]\dataA;}
\legend{A,gr,or,bl,pu}
\end{axis}
\begin{axis}[
axis lines=none,
ytick=\empty,
xtick=\empty,
]
\addlegendimage{empty legend}
\foreach \y in {1,...,4}{
\addplot plot table [x expr=1, col sep=semicolon, header = true, y expr=\thisrowno{\y}/1000]\dataB;}
\legend{B,gr,or,bl,pu}
\end{axis}
\end{tikzpicture}
\end{document}