带有对数刻度的误差线中的误差很大

带有对数刻度的误差线中的误差很大

在以下 MWE 中:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}
    \begin{tikzpicture}
      \begin{axis}[ymode=log, ymin=0.005, ymax=0.1]
        \addplot [mark=diamond]
        plot [error bars/.cd, y dir=both, y explicit]
        table [x=x, y=y, y error=y-err]{%
          x y y-err
          0 0.070 0.003
          1 0.026 0.001
          2 0.018 0.001
          3 0.012 0.02
        };
      \end{axis}
    \end{tikzpicture}
\end{document}

最后一个点的误差太大,因此误差线应该从 延伸到-0.0080.022但是,由于我以对数刻度绘图,因此下限完全消失了,如下所示。在标准绘图库(如 MATLAB 或 matplotlib)中,下限误差线通常延伸到 下方ymin

我知道解决这个问题的一种方法是使用y error minus=y-min, y error plus=y-max并选择合适的y-min。但是,我想知道是否有更好的方法,因为这需要修改所有点,即使只有一个点有问题。更好的是,有没有办法修复的行为error bars

对数刻度中的错误误差​​线

生成正确图表的 Python 代码示例(MATLAB 类似):

import matplotlib.pylab as plt
x = np.arange(0,4)
y = [0.070, 0.026, 0.018, 0.012]
yerr= [0.003, 0.001, 0.001, 0.02]
plt.yscale('log') 
plt.errorbar(x,y,yerr=yerr, fmt='-o')
plt.xlim([-1, 4]); plt.ylim([0.005, 0.1])
plt.show()

正确的 python 输出

答案1

如果您不想修改数据表,可以使用 PGFPlots 的“expr”功能来计算是否超过了 0,并“限制”误差线长度(使用第一个\addplot块和相应的“蓝色”图)。如果您还想强调以负值区域结尾的误差线,则必须添加第二个\addplot(如在符号 1 的答案在类似的问题中(使用第二个\addplot块和相应的“红色”图)。

有关详细信息,请查看代码中的注释。

% used PGFPlots v1.15
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
    % either store the data in an external file or create a loaded table for
    % the "better" solution, so you don't have to repeat the data table
    \pgfplotstableread{
        x   y     y-err
        0.1 0.070 0.003
        1.1 0.026 0.001
        2.1 0.018 0.001
        3.1 0.012 0.02
    }{\loadedtable}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        ymode=log,
        ymin=0.005,
        ymax=0.1,
    ]

        % ---------------------------------------------------------------------
        % just limit error bar length to "zero"
        % ---------------------------------------------------------------------
        \addplot+ [
            mark=diamond,
            error bars/.cd,
                y dir=both,
                y explicit,
        ] table [
            x=x,
            y=y,
            % (nothing special needed here)
            y error plus=y-err,
            % limit error bar to end at `ymin'
            y error minus expr={
                ifthenelse(
                    \thisrow{y} - \thisrow{y-err} <= 0,
                    \thisrow{y} - 1e-4,
                    \thisrow{y-err}%
                )
            },
        ] {
            x y     y-err
            0 0.070 0.003
            1 0.026 0.001
            2 0.018 0.001
            3 0.012 0.02
        };

        % ---------------------------------------------------------------------
        % use different styles for error bars ending in the positive region
        % and for error bars ending in the negative region
        % (inspired by <https://tex.stackexchange.com/a/357036/95441>)
        % ---------------------------------------------------------------------

        % only draw the limited negative error bars (in another style)
        \addplot+ [
            % use `forget plot' so it doesn't count for the cycle list or the
            % legend entries
            forget plot,
            % it should be invisible except for the negative error bar
            draw=none,
            mark=none,
            error bars/.cd,
                % limit it for the negative error bar
                y dir=minus,
                y explicit,
                % don't draw a marker at the end
                error mark=none,
                % and optionally also use another style
                error bar style={
                    dashed,
                },
        ] table [
            x=x,
            y=y,
            y error expr={
                ifthenelse(
                    % calculate if the error bar would end in the negative region
                    \thisrow{y} - \thisrow{y-err} <= 0,
                    % if yes, limit it to "zero" ...
                    \thisrow{y} - 1e-4,
                    % ... and don't draw the error bar otherwise
                    NaN%
                )
            },
        ] {\loadedtable};

        % draw the "normal" error bars
        \addplot+ [
            mark=diamond,
            error bars/.cd,
                y dir=both,
                y explicit,
        ] table [
            x=x,
            y=y,
            y error=y-err,
        ] {\loadedtable};
    \end{axis}
\end{tikzpicture}
\end{document}

该图显示了上述代码的结果

相关内容