I need to make some Weibull analysis and I wanted to make it with numpy and scipy.
Theses analysis are based on Weibull plots :
- on X, time values are reported according to a log scale
- on Y, probability (F) is reported according to a special scale, which lets Weibull random variables fit on a line.
So the pair (t, F) should be plotted on ( ln(t), ln( -ln(1-F)) )
You can find an example of weibull plot here : http://www.itl.nist.gov/div898/handbook/eda/section3/weibplot.htm
Here is my way to make weibull plot with matplotlib :
from numpy import * from matplotlib.ticker import FuncFormatter import pylab as p # I'm used to the ln notation for the natural log from numpy import log as ln # Paramters beta = 5.2 eta = 12 # Genrate 10 numbers following a Weibull distribution x = eta *random.weibull(beta, size=10) F = 1 - exp( -(x/eta)**beta ) # Estimate Weibull parameters lnX = ln(x) lnF = ln( -ln(1-F) ) a, b = polyfit(lnF, lnX, 1) beta0 = 1/a eta0 = exp(b) # ideal line F0 = array([1e-3, 1-1e-3]) x0 = eta0 * (-ln(1-F0))**(1/beta0) lnF0 = ln(-ln(1-F0)) # Weibull plot p.figure() ax = p.subplot(111) p.semilogx(x, lnF, "bs") p.plot(x0, lnF0, 'r-', label="beta= %5G\neta = %.5G" % (beta0, eta0) ) p.grid() p.xlabel('x') p.ylabel('Cumulative Distribution Function') p.legend(loc='lower right') # ticks def weibull_CDF(y, pos): return "%G %%" % (100*(1-exp(-exp(y)))) formatter = FuncFormatter(weibull_CDF) ax.yaxis.set_major_formatter(formatter) yt_F = array([ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99]) yt_lnF = ln( -ln(1-yt_F)) p.yticks(yt_lnF) p.show()
This works, but I 'm pretty sure this could be improved :
Is there a way to use matplotlib.transforms to handle the convertion between F and y=ln(-ln(1-F)) ?
I would like to have vertical lines for major and minor ticks. How can I do that ?
In this case, the log notation for the X axis is not pertinent. How could I switch to a more common floating point notation ?
Any hints ?