在matplotlib中绘制时,正态分布显得过于密集

时间:2017-09-07 15:31:27

标签: python matplotlib plot statistics

我正在尝试估算数据的概率密度函数。就我而言,数据是一个形状为8200 x 8100的卫星图像。 下面,我向您展示PDF的代码(函数' is_outlier'是由在此处发布此代码的人借用的)。我们可以看到,图1中的PDF太密集了。我想,这是由于卫星图像组成的数千个像素。这非常难看。

我的问题是,如何绘制不太密集的PDF?例如,如图2所示。

lst = 'satellite_img.tif' #import the image
lst_flat = lst.flatten() #create 1D array

#the function below removes the outliers
def is_outlier(points, thres=3.5):

    if len(points.shape) == 1:
        points = points[:,None]
    median = np.median(points, axis=0)
    diff = np.sum((points - median)**2, axis=-1)
    diff = np.sqrt(diff)
    med_abs_deviation = np.median(diff)

    modified_z_score = 0.6745 * diff / med_abs_deviation

    return modified_z_score > thres


lst_flat = np.r_[lst_flat]
lst_flat_filtered = lst_flat[~is_outlier(lst_flat)]
fit = stats.norm.pdf(lst_flat_filtered, np.mean(lst_flat_filtered), np.std(lst_flat_filtered))

plt.plot(lst_flat_filtered, fit)
plt.hist(lst_flat_filtered, bins=30, normed=True)
plt.show()

enter image description here

图1

enter image description here 图2

1 个答案:

答案 0 :(得分:1)

问题是PDF图中的x值没有排序,因此绘制的线在随机点之间前后移动,造成你看到的混乱。

两个选项:

  1. 不要绘制线条,只绘制积分(如果你有很多积分则不是很好,但会确认我上面所说的是否正确):

    plt.plot(lst_flat_filtered, fit, 'bo')
    
  2. 在计算PDF并绘制PDF之前对lst_flat_filtered数组进行排序:

    lst_flat = np.r_[lst_flat]
    lst_flat_filtered = np.sort(lst_flat[~is_outlier(lst_flat)])  # Changed this line
    fit = stats.norm.pdf(lst_flat_filtered, np.mean(lst_flat_filtered), np.std(lst_flat_filtered))
    
    plt.plot(lst_flat_filtered, fit)
    
  3. 以下是展示这些行为的一些最小例子:

    重现您的问题:

    import numpy as np
    import scipy.stats as stats
    import matplotlib.pyplot as plt
    
    lst_flat_filtered = np.random.normal(7, 5, 1000)
    
    fit = stats.norm.pdf(lst_flat_filtered, np.mean(lst_flat_filtered), np.std(lst_flat_filtered))
    
    plt.hist(lst_flat_filtered, bins=30, normed=True)
    
    plt.plot(lst_flat_filtered, fit)
    
    plt.show()
    

    enter image description here

    绘图点

    import numpy as np
    import scipy.stats as stats
    import matplotlib.pyplot as plt
    
    lst_flat_filtered = np.random.normal(7, 5, 1000)
    
    fit = stats.norm.pdf(lst_flat_filtered, np.mean(lst_flat_filtered), np.std(lst_flat_filtered))
    
    plt.hist(lst_flat_filtered, bins=30, normed=True)
    
    plt.plot(lst_flat_filtered, fit, 'bo')
    
    plt.show()
    

    enter image description here

    对数据进行排序

    import numpy as np
    import scipy.stats as stats
    import matplotlib.pyplot as plt
    
    lst_flat_filtered = np.sort(np.random.normal(7, 5, 1000))
    
    fit = stats.norm.pdf(lst_flat_filtered, np.mean(lst_flat_filtered), np.std(lst_flat_filtered))
    
    plt.hist(lst_flat_filtered, bins=30, normed=True)
    
    plt.plot(lst_flat_filtered, fit)
    
    plt.show()
    

    enter image description here