python plot normal dağılım


117

Bir ortalama ve bir varyans verildiğinde, normal bir dağılımı çizecek basit bir fonksiyon çağrısı var mı?

Yanıtlar:


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

gaz dağıtımı, ortalama 0 varyans 1


Bu kadar ihtiyaç duyulan satır içi seçeneğim yoktu: %matplotlib inlinearsanın
görünmesini

Kullanımdan kaldırma uyarılarından kaçınmak için, şimdi scipy.stats.norm.pdf(x, mu, sigma)yerine şunu kullanmalısınızmlab.normpdf(x, mu, sigma)
Leonardo Gonzalez

Ek olarak: mathZaten içe aktardığınızda numpyve kullanabilirken neden içe aktarıyorsunuz np.sqrt?
user8408080

1
@ user8408080: Burada performans bir sorun olmamasına rağmen, mathskaler işlemler için kullanma eğilimindeyim çünkü, örneğin, skalarlar math.sqrtüzerinde np.sqrtçalışırken olduğundan çok daha hızlıdır .
unutbu

Y eksenlerini 0 ile 100 arasındaki sayılarla nasıl değiştirebilirim?
Hamid

54

Tüm bunları tek bir aramada yapan bir işlev olduğunu sanmıyorum. Bununla birlikte, Gauss olasılık yoğunluğu işlevini içinde bulabilirsiniz scipy.stats.

Yani bulabileceğim en basit yol şudur:

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

Kaynaklar:


2
Muhtemelen değişmelidir norm.pdfiçin norm(0, 1).pdf. Bu, diğer durumlara uyum sağlamayı / bunun rastgele bir değişkeni temsil eden bir nesne oluşturduğunu anlamayı kolaylaştırır.
Martin Thoma

10

Bunun yerine seaborn'u kullanın, ortalama = 5 std = 1000 değerin 3'ü olan seaborn dağıtım grafiğini kullanıyorum

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

Normal bir dağılım eğrisi elde edeceksiniz


9

Unutbu cevabı doğru. Ancak ortalamamız sıfırdan az ya da çok olabileceğinden, bunu yine de değiştirmek istiyorum:

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

buna :

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

5

Adım adım yaklaşımı tercih ederseniz, aşağıdaki gibi bir çözüm düşünebilirsiniz.

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

Buna yeni döndüm ve matplotlib.mlab MatplotlibDeprecationWarning: scipy.stats.norm.pdfyukarıdaki örneği denerken bana hata mesajı verdiği için scipy'yi kurmak zorunda kaldım . Şimdi örnek:

%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

Yüksekliği ayarlamanın önemli olduğuna inanıyorum, bu nedenle bu işlevi yarattı:

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

sigmaStandart sapma nerede , hyükseklik ve midortalama.

İşte farklı yükseklikler ve sapmalar kullanan sonuç:

görüntü açıklamasını buraya girin


0

kolayca cdf alabilirsiniz. yani cdf üzerinden pdf

    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()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.