35

How do I make plots of a 1-dimensional Gaussian distribution function using the mean and standard deviation parameter values (μ, σ) = (−1, 1), (0, 2), and (2, 3)?

I'm new to programming, using Python.

Thank you in advance!

pythonnewbie
  • 475
  • 2
  • 7
  • 10
  • Possible duplicate of [python pylab plot normal distribution](https://stackoverflow.com/questions/10138085/python-pylab-plot-normal-distribution) – Trevor Boyd Smith Oct 24 '19 at 22:12

5 Answers5

57

With the excellent matplotlib and numpy packages

from matplotlib import pyplot as mp
import numpy as np


def gaussian(x, mu, sig):
    return (
        1.0 / (np.sqrt(2.0 * np.pi) * sig) * np.exp(-np.power((x - mu) / sig, 2.0) / 2)
    )


x_values = np.linspace(-3, 3, 120)
for mu, sig in [(-1, 1), (0, 2), (2, 3)]:
    mp.plot(x_values, gaussian(x_values, mu, sig))

mp.show()

will produce something like

plot showing one-dimensional gaussians produced by matplotlib

danodonovan
  • 19,636
  • 10
  • 70
  • 78
24

The correct form, based on the original syntax, and correctly normalized is:

def gaussian(x, mu, sig):
    return 1./(np.sqrt(2.*np.pi)*sig)*np.exp(-np.power((x - mu)/sig, 2.)/2)
ClimateUnboxed
  • 7,106
  • 3
  • 41
  • 86
  • This is the only answer with normalization that matches scipy. Needed to add a couple "np", and the decimal marks are superfluous `1/(np.sqrt(2*np.pi)*sig)*np.exp(-np.power((x - mu)/sig, 2)/2)` – Kyle McDonald Oct 31 '19 at 09:57
  • 1
    Finally someone who remembered π in the denominator! – GreenhouseVeg Jun 03 '20 at 13:57
  • Instead of `np.power(x, 2)` one could use `np.square(x)` (which might be a bit faster due to specialization). – Tom Pohl Mar 31 '23 at 06:08
21

you can read this tutorial for how to use functions of statistical distributions in python. https://docs.scipy.org/doc/scipy/tutorial/stats.html

from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np 

#initialize a normal distribution with frozen in mean=-1, std. dev.= 1
rv = norm(loc = -1., scale = 1.0)
rv1 = norm(loc = 0., scale = 2.0)
rv2 = norm(loc = 2., scale = 3.0)

x = np.arange(-10, 10, .1)

#plot the pdfs of these normal distributions 
plt.plot(x, rv.pdf(x), x, rv1.pdf(x), x, rv2.pdf(x))
jeffrey_t_b
  • 1,779
  • 12
  • 18
XValidated
  • 981
  • 8
  • 12
8

In addition to previous answers, I recommend to first calculate the ratio in the exponent, then taking the square:

def gaussian(x,x0,sigma):
  return np.exp(-np.power((x - x0)/sigma, 2.)/2.)

That way, you can also calculate the gaussian of very small or very large numbers:

In: gaussian(1e-12,5e-12,3e-12)
Out: 0.64118038842995462
PhMota
  • 163
  • 1
  • 6
Felix
  • 659
  • 2
  • 10
  • 24
7

You are missing a parantheses in the denominator of your gaussian() function. As it is right now you divide by 2 and multiply with the variance (sig^2). But that is not true and as you can see of your plots the greater variance the more narrow the gaussian is - which is wrong, it should be opposit.

So just change the gaussian() function to:

def gaussian(x, mu, sig):
    return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))
cvt1982
  • 87
  • 1
  • 1
  • 1
    This formula is wrong because if you integrate it from minus infinity to infinity you will get sqrt(2)*sqrt(pi) that isn't right. The right formula is 1/sqrt(2*pi)*exp(-x^2/2). Although, in this form, its mean is 0 and variance is 1, you can shift and scale this gaussian as you like – Eugene Mar 15 '17 at 05:45