python plot distribusi normal


116

Diberikan mean dan varians, apakah ada pemanggilan fungsi sederhana yang akan menggambarkan distribusi normal?

Jawaban:


208
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import math

mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, stats.norm.pdf(x, mu, sigma))
plt.show()

distro gas, rata-rata adalah 0 varian 1


Saya tidak memiliki opsi inline yang sangat dibutuhkan: %matplotlib inlineagar plotnya muncul
hum3

Untuk menghindari peringatan bantahan, sekarang Anda harus menggunakan scipy.stats.norm.pdf(x, mu, sigma)bukannyamlab.normpdf(x, mu, sigma)
Leonardo Gonzalez

Selain itu: Mengapa Anda mengimpor mathketika Anda sudah mengimpor numpydan dapat menggunakan np.sqrt?
pengguna8408080

1
@ user8408080: Meskipun kinerja tidak menjadi masalah di sini, saya cenderung menggunakan mathuntuk operasi skalar karena, misalnya, jauh math.sqrtlebih cepat daripada np.sqrtsaat beroperasi pada skalar.
unutbu

Bagaimana cara mengubah sumbu Y menjadi angka antara 0 hingga 100?
Hamid

54

Saya tidak berpikir ada fungsi yang melakukan semua itu dalam satu panggilan. Namun Anda dapat menemukan fungsi kepadatan probabilitas Gaussian di scipy.stats.

Jadi cara paling sederhana yang bisa saya lakukan adalah:

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

# Plot between -10 and 10 with .001 steps.
x_axis = np.arange(-10, 10, 0.001)
# Mean = 0, SD = 2.
plt.plot(x_axis, norm.pdf(x_axis,0,2))
plt.show()

Sumber:


2
Anda mungkin harus berubah norm.pdfmenjadi norm(0, 1).pdf. Ini membuatnya lebih mudah untuk menyesuaikan dengan kasus lain / untuk memahami bahwa ini menghasilkan objek yang mewakili variabel acak.
Martin Thoma

10

Gunakan seaborn sebagai gantinya saya menggunakan distplot dari seaborn dengan mean = 5 std = 3 dari 1000 nilai

value = np.random.normal(loc=5,scale=3,size=1000)
sns.distplot(value)

Anda akan mendapatkan kurva distribusi normal


9

Jawaban Unutbu benar. Tetapi karena mean kita bisa lebih atau kurang dari nol, saya masih ingin mengubah ini:

x = np.linspace(-3 * sigma, 3 * sigma, 100)

untuk ini :

x = np.linspace(-3 * sigma + mean, 3 * sigma + mean, 100)

5

Jika Anda lebih suka menggunakan pendekatan langkah demi langkah, Anda dapat mempertimbangkan solusi seperti berikut

import numpy as np
import matplotlib.pyplot as plt

mean = 0; std = 1; variance = np.square(std)
x = np.arange(-5,5,.01)
f = np.exp(-np.square(x-mean)/2*variance)/(np.sqrt(2*np.pi*variance))

plt.plot(x,f)
plt.ylabel('gaussian distribution')
plt.show()

1

Saya baru saja kembali ke ini dan saya harus menginstal scipy karena matplotlib.mlab memberi saya pesan kesalahan MatplotlibDeprecationWarning: scipy.stats.norm.pdfketika mencoba contoh di atas. Jadi sampelnya sekarang:

%matplotlib inline
import math
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats


mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, scipy.stats.norm.pdf(x, mu, sigma))

plt.show()

1

Saya percaya itu penting untuk mengatur ketinggian, jadi buatlah fungsi ini:

def my_gauss(x, sigma=1, h=1, mid=0):
    from math import exp, pow
    variance = pow(sdev, 2)
    return h * exp(-pow(x-mid, 2)/(2*variance))

Dimana sigmadeviasi standar, hadalah tinggi danmid mean.

Berikut adalah hasil menggunakan ketinggian dan deviasi yang berbeda:

masukkan deskripsi gambar di sini


0

Anda bisa mendapatkan cdf dengan mudah. jadi pdf melalui cdf

    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.interpolate
    import scipy.stats

    def setGridLine(ax):
        #http://jonathansoma.com/lede/data-studio/matplotlib/adding-grid-lines-to-a-matplotlib-chart/
        ax.set_axisbelow(True)
        ax.minorticks_on()
        ax.grid(which='major', linestyle='-', linewidth=0.5, color='grey')
        ax.grid(which='minor', linestyle=':', linewidth=0.5, color='#a6a6a6')
        ax.tick_params(which='both', # Options for both major and minor ticks
                        top=False, # turn off top ticks
                        left=False, # turn off left ticks
                        right=False,  # turn off right ticks
                        bottom=False) # turn off bottom ticks

    data1 = np.random.normal(0,1,1000000)
    x=np.sort(data1)
    y=np.arange(x.shape[0])/(x.shape[0]+1)

    f2 = scipy.interpolate.interp1d(x, y,kind='linear')
    x2 = np.linspace(x[0],x[-1],1001)
    y2 = f2(x2)

    y2b = np.diff(y2)/np.diff(x2)
    x2b=(x2[1:]+x2[:-1])/2.

    f3 = scipy.interpolate.interp1d(x, y,kind='cubic')
    x3 = np.linspace(x[0],x[-1],1001)
    y3 = f3(x3)

    y3b = np.diff(y3)/np.diff(x3)
    x3b=(x3[1:]+x3[:-1])/2.

    bins=np.arange(-4,4,0.1)
    bins_centers=0.5*(bins[1:]+bins[:-1])
    cdf = scipy.stats.norm.cdf(bins_centers)
    pdf = scipy.stats.norm.pdf(bins_centers)

    plt.rcParams["font.size"] = 18
    fig, ax = plt.subplots(3,1,figsize=(10,16))
    ax[0].set_title("cdf")
    ax[0].plot(x,y,label="data")
    ax[0].plot(x2,y2,label="linear")
    ax[0].plot(x3,y3,label="cubic")
    ax[0].plot(bins_centers,cdf,label="ans")

    ax[1].set_title("pdf:linear")
    ax[1].plot(x2b,y2b,label="linear")
    ax[1].plot(bins_centers,pdf,label="ans")

    ax[2].set_title("pdf:cubic")
    ax[2].plot(x3b,y3b,label="cubic")
    ax[2].plot(bins_centers,pdf,label="ans")

    for idx in range(3):
        ax[idx].legend()
        setGridLine(ax[idx])

    plt.show()
    plt.clf()
    plt.close()
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.