pythoncontourgaussian

Contour plotting with gaussian_kde. It always draws 0.000 line. How to avoid it?


I'm trying to plot some equipotential lines with gaussian_kde function. However, i noticed that it always draws the most outer line with probability 0.000. I cannot find anyway to avoid it.

An example code:

    from __future__ import division
    import pandas
    import numpy as np
    import matplotlib.pyplot as plt
    import math
    
    import matplotlib.tri as tri
    
    import random
    import scipy as sp
    from scipy import stats
    import pylab as pl
    
    fig, axes = plt.subplots(1, 3, figsize=(18, 6), dpi=150)
    
    x5min, x5max = -500,500
    y5min, y5max = -500,500
    a1=random.sample(range(-40, 40), 30)
    a2=random.sample(range(-40, 40), 30)
    
    
    x5, y5 = sp.mgrid[x5min:x5max:100j, y5min:y5max:100j]
    positions5 = sp.vstack([x5.ravel(), y5.ravel()])
    values5 = sp.vstack([a1, a2])
    kernel5 = stats.gaussian_kde(values5)
    kde5 = sp.reshape(kernel5(positions5).T, x5.shape)
    
    # plotting
    axes[1].contour(x5,y5,kde5,30,colors='g')

enter image description here

As you can see in the plot. There is 0.000 prob line marked with arrows. Why is it drawing this? I seek a way to disable it and cant find anyway. Any ideas?


Solution

  • I believe that is because contour does automatically set the minimum level to the minimum of the function and your function is very dense in a narrow range so it looks weird, for example:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x, y = np.linspace(-10, 10, 1000), np.linspace(-10, 10, 1000)
    X, Y = np.meshgrid(x, y)
    
    Z = np.exp(-(X**2 + Y**2) / 0.1)
    
    plt.contour(x, y, Z)
    plt.show()
    

    Will show this:

    enter image description here

    If instead we set the levels manually:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x, y = np.linspace(-10, 10, 1000), np.linspace(-10, 10, 1000)
    
    X, Y = np.meshgrid(x, y)
    
    Z = np.exp(-(X**2 + Y**2) / 0.1)
    levels = np.linspace(0.1, np.amax(Z), 30)
    plt.contour(x, y, Z, levels=levels)
    
    plt.show()
    

    This doesn't happen:

    enter image description here

    Of course you can then tweak your limits to make this visualization better:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x, y = np.linspace(-10, 10, 1000), np.linspace(-10, 10, 1000)
    
    X, Y = np.meshgrid(x, y)
    
    Z = np.exp(-(X**2 + Y**2) / 0.1)
    levels = np.linspace(0.1, np.amax(Z), 30)
    fig, ax = plt.subplots()
    
    ax.contour(x, y, Z, levels=levels)
    ax.set_xlim(-0.75, 0.75)
    ax.set_ylim(-0.75, 0.75)
    
    plt.show()
    

    enter image description here