仅绘制对数间隔的样本

仅绘制对数间隔的样本

我有一个包含许多条目的数据文件,数量级为 10000。我想用线绘制所有条目,用点和误差线绘制一小部分条目(无法在 10000 个样本上绘制误差线)。使用 可以轻松绘制每个 N each nth point=N,但我使用的是半对数轴,因此我想绘制每个 10^N(甚至更好的 2^N)。

现在我预处理数据文件并生成另一个包含有趣样本子集的文件,有没有办法让 pgfplots 做到这一点?

编辑

这是一个最小的工作示例:

\documentclass[10pt,a4paper]{article}

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

\begin{document}

\begin{tikzpicture}
  \begin{semilogxaxis}
    \addplot+ table[col sep=comma, x=x, y=y, each nth point=100]
        {aaa.txt};
  \end{semilogxaxis}
\end{tikzpicture}

\end{document}

文件aaa.txt是这样的:

x,y,var
1,1,0.7257899338880273
2,2,0.5103550634511824
3,3,0.8469400089552953
4,4,0.8351651602434369
5,5,0.07359721861492374
6,6,0.3107395762944515
7,7,0.9151522020717112
8,8,0.4967609141914707
9,9,0.2218284814240239
10,10,0.7166461578126254
...

我使用 Ruby 脚本生成了坐标1.step(1024) { |i| puts "#{i},#{i},#{rand}" }using nth point=100它只在 100、200、300 处绘图...我尝试用x filter建议的脚本替换它,但它继续绘制整个数据文件(它没有在命令行上说它因为过滤器而跳过了点,就像它对 所做的那样using nth point)。

答案1

each nth point=N用以下内容替换应该有效:

x filter/.code={\pgfmathparse{divide(#1,equal(#1,floor(#1))}}

解释一下:x filter顾名思义,允许坐标过滤。代码将坐标作为#1(如果轴是对数,则为它的对数,这里就是这种情况)提供,并对其进行一些计算。如果结果为数字,则将其用作坐标,如果不是,则将其丢弃。

这里我们想丢弃 log(x) 不是整数的情况,因此我们测试 log(x) 和 Ceil(log(x)) 是否相等。如果它们不相等,代码将执行除以零的操作,结果为inf和 被丢弃。另一方面,如果它们相等,则将 log(x) 除以 1 会返回 log(x)。

如果您想要过滤 2 的幂,请务必添加log basis x=2您的环境选项。semilogxaxis

现在,这是理论部分。但是,如果您尝试将上述代码与您的示例结合使用,它将无法工作,因为pgfmath计算以 2 为底的对数时舍入效果不佳,例如 log2(8)=2.99997。以下代码可以工作。请记住,它仍然依赖于近似计算,因此,对于较大的值,它可能会失败。

\documentclass[10pt,a4paper]{article}

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

\begin{document}

\begin{tikzpicture}
  \begin{semilogxaxis}[unbounded coords=discard,
    log basis x=2,
    x filter/.code={\pgfmathparse{divide(#1,(equal(2^(#1),2^(round(#1)))))}}
    ]
  \addplot+ table[col sep=comma,x=x, y=y]
    {aaa.txt};
  \end{semilogxaxis}
\end{tikzpicture}

\end{document}

相关内容