将来自不同来源的条形图与每个 xlabel 对齐

将来自不同来源的条形图与每个 xlabel 对齐

我有一个 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偏移将相等。AB

在此处输入图片描述

\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}

在此处输入图片描述

相关内容