Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何绘制正态分布?_Python_Matplotlib - Fatal编程技术网

Python 如何绘制正态分布?

Python 如何绘制正态分布?,python,matplotlib,Python,Matplotlib,给定一个均值和方差,是否有一个简单的函数调用来绘制正态分布 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, m

给定一个均值和方差,是否有一个简单的函数调用来绘制正态分布

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

我认为没有一个函数可以在一次调用中完成所有这些功能。但是,您可以在
scipy.stats
中找到高斯概率密度函数

所以我能想到的最简单的方法是:

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()
资料来源:

Unutbu的答案是正确的。 但因为我们的平均值可以大于或小于零,我仍然想改变这一点:

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

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

如果你喜欢使用一步一步的方法,你可以考虑如下的解决方案:

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

您可以轻松获得cdf。所以pdf通过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()

我刚刚回到这里,在尝试上面的示例时,matplotlib.mlab给了我错误消息,因此我必须安装scipy。因此,现在的样本是:

%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()
改用seaborn 我使用seaborn的distplot,平均值=5 std=3/1000

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

您将获得正态分布曲线

我认为设置高度很重要,因此创建了此函数:

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))
其中,
sigma
是标准偏差,
h
是高度,
mid
是平均值

以下是使用不同高度和偏差得出的结果:


您可能应该将
norm.pdf
更改为
norm(0,1.pdf
)。这使得调整到其他情况/理解这会生成一个表示随机变量的对象变得更容易。我没有需要的内联选项:
%matplotlib inline
要使绘图显示出来以避免弃用警告,现在应该使用
scipy.stats.norm.pdf(x,mu,sigma)
而不是
mlab.normpdf(x,mu,sigma)
另外:当您已经导入
numpy
并且可以使用
np.sqrt
时,为什么要导入
math
?@user8408080:虽然性能在这里不是问题,但我倾向于使用
math
进行标量操作,因为,当在标量上操作时,
math.sqrt
np.sqrt
快一个数量级以上。@哈米德:我想你不能将Y轴更改为0到100之间的数字。这是代表概率密度函数的正态分布曲线。Y轴值表示概率密度。曲线下的总面积导致概率值为1。由于Y轴所代表的内容,在Y轴上的值甚至不会达到1。我希望这是有道理的。
import math  
import matplotlib.pyplot as plt
import numpy
import pandas as pd


def normal_pdf(x, mu=0, sigma=1):
    sqrt_two_pi = math.sqrt(math.pi * 2)
    return math.exp(-(x - mu) ** 2 / 2 / sigma ** 2) / (sqrt_two_pi * sigma)


df = pd.DataFrame({'x1': numpy.arange(-10, 10, 0.1), 'y1': map(normal_pdf, numpy.arange(-10, 10, 0.1))})

plt.plot('x1', 'y1', data=df, marker='o', markerfacecolor='blue', markersize=5, color='skyblue', linewidth=1)
plt.show()