![绘制 Q-Q 图 (pgfplots)](https://linux22.com/image/308845/%E7%BB%98%E5%88%B6%20Q-Q%20%E5%9B%BE%20(pgfplots).png)
我从 PGFplots 文档中看到,没有原生支持Q-Q 图。
但是,由于我使用 PGFplots 来全部我的其他图表,我也想用它来显示 Q-Q 图。主要原因是一致性。
我有一个用 R 绘制的示例 Q-Q 图,它看起来与我的其他图形完全不同:
有人遇到过这种情况吗?我在 TeX 上搜索过,但搜索没有得到相关结果。要么是搜索有问题(搜索“QQ”非常不方便,即使在 Google 上),或者还没有相关的问题/答案(在 TeX 上)。
可以使用 gnuplot 来实现吗?或者可以用 pgfplots 绘制原生散点图,然后以某种方式预先转换数据?如果可以,怎么做?
答案1
您可以使用 PGFPlots 来执行此操作,尽管我可能会在 LaTeX 之外进行此分析(例如使用 R、Python 或 Matlab),将数据导出为表格并使用 PGFPlots 绘制该表。
如果你想完全使用 LaTeX,你可以先使用以下方法读取、排序和计算数据:
\pgfplotstablesort{\sorted}{datafile.txt}
\pgfplotstablegetrowsof{\datatable}
\edef\numrows{\pgfplotsretval}
然后你需要一种计算正态分布相应分位数的方法,即所谓的概率函数,这需要逆误差函数。这可以是足够精确地近似使用
declare function={inverf(\x)=\x/abs(\x) * sqrt( sqrt( (4.3307 + ln(1-\x^2)/2 )^2 - ln(1-\x^2)/0.147 ) - (4.3307 + ln(1-\x^2)/2);}
然后你可以使用以下方式定义 probit 函数
declare function={normq(\p)=1.4142 * inverf(2*\p-1);}
这就是 QQ 图所需的全部内容:
\addplot [only marks, mark=*] table [x index=0, y index=0, y expr=normq(\coordindex/\numrows)] {\sorted};
以下是使用 Python 生成的数据的完整示例numpy.random.normal(size=100)*5+10
\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{document}
\pgfplotstableread{
1.46365192956
9.22330318663
15.4712651178
8.87219994452
9.92824632322
8.69935247007
17.8222081627
14.3601041144
22.9047131581
8.05005282649
9.650706465
17.2352199894
7.76424153088
10.370245979
7.12513239519
2.64730407495
7.2072208982
14.7683650153
14.0063750733
19.324137585
2.40858604381
18.0368674939
8.02681240716
8.26418810694
12.1941169594
9.62080674537
3.24961728242
3.27316960403
17.9038479307
7.40481579419
10.814441695
8.40741573499
6.08031313304
13.1781459953
10.206134367
15.0864695726
9.03013313987
4.46906993699
9.27542593922
11.387166818
5.34088290758
7.35790199406
11.8693581818
10.8557924873
13.969617244
10.6354692297
3.03046442179
6.60358722529
12.2836888554
8.46665782108
13.9221860476
15.1323993544
7.16507829073
5.69317421704
15.4624253296
16.9138444234
6.44259653768
16.4478862876
3.46926929558
10.8862152053
10.4982459647
13.079580222
10.8219448481
12.1887774019
2.27608579327
4.21879129366
8.6626149873
3.05616084556
12.2628717929
3.07385860151
12.1834370192
7.86785100457
22.3039915506
7.6084726129
-3.38040559575
-4.77264935147
13.9493967532
14.1237678197
6.79956429934
8.7032357113
6.08645967617
9.19491098171
17.1651582777
4.7041931405
3.78091331321
5.20247821499
13.8921717364
6.09560236506
18.5811121283
10.3758110312
8.95955605147
12.4511725524
4.67834498484
11.0234433275
15.364443589
8.23928346825
6.30079928878
9.95330967273
12.5692010856
11.8362767596
}\datatable
\pgfplotstablesort{\sorted}{\datatable}
\pgfplotstablegetrowsof{\datatable}
\edef\numrows{\pgfplotsretval}
\begin{tikzpicture}[
declare function={inverf(\x)=\x/abs(\x) * sqrt( sqrt( (4.3307 + ln(1-\x^2)/2 )^2 - ln(1-\x^2)/0.147 ) - (4.3307 + ln(1-\x^2)/2);},
declare function={normq(\p)=1.4142 * inverf(2*\p-1);}
]
\begin{axis}
\addplot [only marks, mark=*] table [x index=0, y index=0, y expr=normq(\coordindex/\numrows)] {\sorted};
\end{axis}
\end{tikzpicture}
\end{document}