我有一个包含许多条目的数据文件,数量级为 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}