distribuzione normale del diagramma di Python


116

Data una media e una varianza, esiste una semplice chiamata di funzione che traccerà una distribuzione normale?

Risposte:


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

distribuzione gass, la media è 0 varianza 1


Non avevo l'opzione in linea così necessaria: %matplotlib inlineper far apparire la trama
hum3

Per evitare avvisi di deprecazione, ora dovresti usare al scipy.stats.norm.pdf(x, mu, sigma)posto dimlab.normpdf(x, mu, sigma)
Leonardo Gonzalez

Inoltre: perché importi mathquando hai già importato numpye potresti usarlo np.sqrt?
user8408080

1
@ user8408080: Sebbene le prestazioni non siano un problema qui, tendo a usarlo mathper operazioni scalari poiché, ad esempio, math.sqrtè più veloce di una grandezza rispetto a np.sqrtquando si opera su scalari.
unutbu

Come posso modificare gli assi Y in numeri compresi tra 0 e 100?
Hamid

54

Non credo che ci sia una funzione che fa tutto questo in una singola chiamata. Tuttavia puoi trovare la funzione di densità di probabilità gaussiana in scipy.stats.

Quindi il modo più semplice che posso trovare è:

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

fonti:


2
Probabilmente dovresti cambiare norm.pdfin norm(0, 1).pdf. Ciò rende più facile adattarsi ad altri casi / capire che questo genera un oggetto che rappresenta una variabile casuale.
Martin Thoma

10

Usa seaborn invece sto usando distplot di seaborn con media = 5 std = 3 di 1000 valori

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

Otterrai una normale curva di distribuzione


9

La risposta Unutbu è corretta. Ma poiché la nostra media può essere più o meno di zero, vorrei comunque cambiare questo:

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

a questa :

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

5

Se preferisci utilizzare un approccio graduale, potresti prendere in considerazione una soluzione come segue

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

Sono appena tornato a questo e ho dovuto installare scipy poiché matplotlib.mlab mi ha dato il messaggio di errore MatplotlibDeprecationWarning: scipy.stats.norm.pdfdurante il tentativo di esempio sopra. Quindi il campione è ora:

%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

Credo che sia importante impostare l'altezza, quindi ho creato questa funzione:

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

Dov'è sigmala deviazione standard, hè l'altezza ed midè la media.

Ecco il risultato utilizzando diverse altezze e deviazioni:

inserisci qui la descrizione dell'immagine


0

puoi ottenere facilmente cdf. quindi pdf tramite 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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.