Python中Matlab的normplot等效方案是什么?
有没有类似于MATLAB中normplot
的Python函数?也许可以在matplotlib中找到?
MATLAB的写法:
x = normrnd(10,1,25,1);
normplot(x)
结果是:
我尝试使用matplotlib和numpy模块来确定数组中值的概率或百分位数,但输出的图表y轴的刻度是线性的,这和MATLAB的图表不一样。
import numpy as np
import matplotlib.pyplot as plt
data =[-11.83,-8.53,-2.86,-6.49,-7.53,-9.74,-9.44,-3.58,-6.68,-13.26,-4.52]
plot_percentiles = range(0, 110, 10)
x = np.percentile(data, plot_percentiles)
plt.plot(x, plot_percentiles, 'ro-')
plt.xlabel('Value')
plt.ylabel('Probability')
plt.show()
结果是:
那么,如何才能像第一个图那样调整刻度呢?
谢谢。
4 个回答
也许你可以使用scipy库中的probplot
函数(在scipy.stats
里),这个函数看起来和MATLAB里的normplot功能相似:
这个函数可以计算样本数据与指定的理论分布之间的概率图的分位数。
而且,
probplot
还可以选择性地为数据计算一个最佳拟合线,并使用Matplotlib或者你指定的绘图函数来展示结果。
http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.probplot.html
不过,这个函数并不能解决你提到的y轴刻度不同的问题。
我很确定matplotlib没有提供类似的功能。
当然,这种事情是可以做到的,但你需要重新调整你的数据,并更改y轴的刻度和标签以匹配,或者如果你打算经常这样做,或许可以编写一个新的缩放方式,应用到matplotlib的坐标轴上,就像这个例子所示:http://matplotlib.sourceforge.net/examples/api/custom_scale_example.html。
虽然这个回答有点晚,但我刚遇到同样的问题,找到了解决办法,觉得值得分享一下。
正如joris提到的,probplot函数和normplot是相似的,但它们得到的结果是累积分布函数的形式。Scipy.stats也提供了一个函数,可以把这些值进行转换。
累积分布函数(cdf)可以转化为百分位数(percentile)
stats.'distribution function'.cdf(cdf_value)
百分位数(percentile)也可以转化为累积分布函数(cdf)
stats.'distribution function'.ppf(percentile_value)
举个例子:
stats.norm.ppf(percentile)
如果你想得到一个和normplot一样的y轴,可以替换掉cdf的刻度:
from scipy import stats
import matplotlib.pyplot as plt
nsample=500
#create list of random variables
x=stats.t.rvs(100, size=nsample)
# Calculate quantiles and least-square-fit curve
(quantiles, values), (slope, intercept, r) = stats.probplot(x, dist='norm')
#plot results
plt.plot(values, quantiles,'ob')
plt.plot(quantiles * slope + intercept, quantiles, 'r')
#define ticks
ticks_perc=[1, 5, 10, 20, 50, 80, 90, 95, 99]
#transfrom them from precentile to cumulative density
ticks_quan=[stats.norm.ppf(i/100.) for i in ticks_perc]
#assign new ticks
plt.yticks(ticks_quan,ticks_perc)
#show plot
plt.grid()
plt.show()
结果是: