7

Is there a python equivalent function similar to normplot from MATLAB? Perhaps in matplotlib?

MATLAB syntax:

x = normrnd(10,1,25,1);
normplot(x)

Gives:

enter image description here

I have tried using matplotlib & numpy module to determine the probability/percentile of the values in array but the output plot y-axis scales are linear as compared to the plot from 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() 

Gives: enter image description here

Else, how could the scales be adjusted as in the first plot?

Thanks.

siva
  • 2,105
  • 4
  • 20
  • 37

4 Answers4

7

A late answer, but I just came across the same problem and found a solution, that is worth sharing. I guess.

As joris pointed out the probplot function is an equivalent to normplot, but the resulting distribution is in form of the cumulative density function. Scipy.stats also offers a function, to convert these values.

cdf -> percentile

stats.'distribution function'.cdf(cdf_value)

percentile -> cdf

stats.'distribution function'.ppf(percentile_value)

for example:

stats.norm.ppf(percentile)

To get an equivalent y-axis, like normplot, you can replace the cdf-ticks:

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()

The result:

probability plot with matplotlib

Kaioto
  • 108
  • 1
  • 5
2

I'm fairly certain matplotlib doesn't provide anything like this.

It's possible to do, of course, but you'll have to either rescale your data and change your y axis ticks/labels to match, or, if you're planning on doing this often, perhaps code a new scale that can be applied to matplotlib axes, like in this example: http://matplotlib.sourceforge.net/examples/api/custom_scale_example.html.

weronika
  • 2,561
  • 2
  • 24
  • 30
2

Maybe you can use the probplot function of scipy (scipy.stats), this seems to me an equivalent for MATLABs normplot:

Calculate quantiles for a probability plot of sample data against a specified theoretical distribution.

probplot optionally calculates a best-fit line for the data and plots the results using Matplotlib or a given plot function.

http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.probplot.html

But is does not solve your problem of the different y-axis scale.

joris
  • 133,120
  • 36
  • 247
  • 202
1

Using matplotlib.semilogy will get closer to the matlab output.

talonmies
  • 70,661
  • 34
  • 192
  • 269