PGFPlots 中的水平条形图:“点元”与对齐混乱

PGFPlots 中的水平条形图:“点元”与对齐混乱

我正在绘制一个相当不寻常的条形图来显示一项小型调查的结果。图表的轴在负域和正域中延伸。但是,没有零,所有值都是正的。这听起来相当复杂,所以这里有一张图片:

文本A

看到实际值会很好。 PGFPlots 手册第 4.4.4 节建议nodes near coords, nodes near coords align = {horizontal}在这些情况下使用。结果如下:

文本B

这看起来不错,但值显然是错误的。为了让条形图忘记实际上没有零值,我更改了绘图样式中的 x 刻度并减去 1。因此,条形旁边显示的值是 PGFPlots 的坐标,也是我输入的唯一坐标。

现在,有两个选择:在编译期间计算它|x|+1(第一张图片)或明确添加正确的值(第二张图片):

文本C 文本D

这两个选项都以不同的方式弄乱了布局,我不知道如何正确定位节点。这是生成所示图表的 MWE 代码:

\documentclass[11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\usepackage{floatrow}
\usepackage{subfigure}

\pgfplotsset{TestBar/.style={% Overall settings
    width = 0.75\textwidth,
    line width=1pt,
    tick style={line width=0.8pt},
    xmin = -8, xmax = 8,
    xtick       = {-8,-6,-4,-2, 0, 2, 4, 6, 8},
    xticklabels = { 9, 7, 5, 3, 1, 3, 5, 7, 9},
    xmajorgrids = true,
    minor x tick num = 1,
    tick align = outside,
    xtick pos = left, ytick pos = left,
    xbar,
    height = 3cm,
    enlarge y limits = 0.5, ytick = {1,2},
    yticklabels = {C2, C1}}
}

\pgfplotsset{TestBarY/.style={% Draw y-Axis without anything
    width = 0.75\textwidth,
    height = 3cm,
    line width = 1pt,
    xmin = -8, xmax = 8,
    xmajorgrids = false,
    xtick = \empty, ytick = \empty,
    no markers,
    minor x tick num = 1,
    axis y line* = center}
}

\pgfplotsset{TextA/.style={}}% Show no values

\pgfplotsset{TextB/.style={% Show value as given in the coordinates.
    nodes near coords,
    nodes near coords align = {horizontal}}
}

\pgfplotsset{TextC/.style={% Calculate value in point-meta.
    nodes near coords,
    nodes near coords align={horizontal},
    point meta = {abs(x)+1}}
}

\pgfplotsset{TextD/.style={% Caption explicitly added in point-meta.
    nodes near coords,
    nodes near coords align={horizontal},
    point meta = explicit symbolic}
}

\begin{document}

\begin{figure}[htb]
\subfigure[TextA: no text.]{
\begin{tikzpicture}
    \begin{axis}[TestBar]
        \addplot[TextA] coordinates { (2.555,1) (-1.279,2) };
    \end{axis}

    \begin{axis}[TestBarY]\addplot coordinates {(0,0)};\end{axis}
\end{tikzpicture}}\
\subfigure[TextB: node-text from coordinates.]{
\begin{tikzpicture}
    \begin{axis}[TestBar]
        \addplot[TextB] coordinates { (2.555,1) (-1.279,2) };
    \end{axis}

    \begin{axis}[TestBarY]\addplot coordinates {(0,0)};\end{axis}
\end{tikzpicture}}\
\subfigure[TextC: node-text calculated in \emph{point meta} as abs(x)+1.]{
\begin{tikzpicture}
    \begin{axis}[TestBar]
        \addplot[TextC] coordinates { (2.555,1) (-1.279,2) };
    \end{axis}

    \begin{axis}[TestBarY]\addplot coordinates {(0,0)};\end{axis}
\end{tikzpicture}}\
\subfigure[TextD: node-text explicitly added to \emph{point meta}.]{
\begin{tikzpicture}
    \begin{axis}[TestBar]
        \addplot[TextD] coordinates { (2.555,1) [3.56] (-1.279,2) [2.28] };
    \end{axis}

    \begin{axis}[TestBarY]\addplot coordinates {(0,0)};\end{axis}
\end{tikzpicture}}
\end{figure}

\end{document}

答案1

对齐horizontal选项通过查看值的符号来确定将标签放在条形图的左侧还是右侧meta。通过将其转换为绝对值,所有标签最终都会位于右侧。实现您要执行的操作的一种方法是仅在将meta值打印在标签中时转换它。您可以使用

nodes near coords={
    \pgfkeys{/pgf/fpu=true}
    \pgfmathparse{abs(\pgfplotspointmeta)+1}
    \pgfmathprintnumber{\pgfmathresult}
}

fpu首先需要打开库,因为该meta值已转换为浮点表示。然后您可以进行计算,最后使用 打印数字\pgfmathprintnumber

额外提示:在 x=0 处绘制一条线,你不必使用一个全新的轴。关键

before end axis/.code={
        \draw ({rel axis cs:0,0}-|{axis cs:0,0}) -- ({rel axis cs:0,1}-|{axis cs:0,0});
    }

将绘制一条从 x=0 处的图底部开始到顶部的线,无论轴限制如何。

完整代码如下:

\documentclass[11pt]{article}
\usepackage{pgfplots}

\pgfplotsset{
    TestBar/.style={% Overall settings
        width = 0.75\textwidth,
        line width=1pt,
        tick style={line width=0.8pt},
        xmin = -8, xmax = 8,
        xtick       = {-8,-6,-4,-2, 0, 2, 4, 6, 8},
        xticklabels = { 9, 7, 5, 3, 1, 3, 5, 7, 9},
        xmajorgrids = true,
        minor x tick num = 1,
        tick align = outside,
        xtick pos = left, ytick pos = left,
        xbar,
        height = 3cm,
        enlarge y limits = 0.5, ytick = {1,2},
        yticklabels = {C2, C1},
        nodes near coords={
            \pgfkeys{/pgf/fpu=true}%
            \pgfmathparse{abs(\pgfplotspointmeta)+1}%
            \pgfmathprintnumber{\pgfmathresult}
        },
        nodes near coords align = {horizontal},
        before end axis/.code={
            \draw ({rel axis cs:0,0}-|{axis cs:0,0}) -- ({rel axis cs:0,1}-|{axis cs:0,0});
        }
    }
}




\begin{document}

\begin{tikzpicture}
    \begin{axis}[TestBar]
        \addplot [] coordinates { (2.555,1) (-1.279,2) };
    \end{axis}
\end{tikzpicture}

\end{document}

相关内容