10
votes

I'm in the process of making a scatter plot from thousands of points in python using pyplot. My problem is that they tend to concentrate in one place, and it's just a giant blob of points.

Is there some kind of functionality to make pyplot plot points up until it reaches some critical density and then make it a contour plot?

My question is similar to this one, where the example plot has contour lines, in which the color represents the density of the plotted points.

Super cool contour plot

This is what my data looks likeLots of yellow points

1
You might not have to make a switch. If the points are loose, then the contour lines will not be too visible, but the points themselves will convey the information. However if the points are dense, as in the image above, then they will create a nice background over which the contour should be visible. So I suggest first using a scatter with filled markers, and a contour on top of that. You just have to define a density which you can contour plot. And if this doesn't work for you, then try doing a switch, probably to a contourf. - Andras Deak
why not just reducing the size of your dots? or use some transparency which will effectively give you the density as a gray scale? - Julien

1 Answers

9
votes

First, you need a density estimation of you data. Depending on the method you choose, varying result can be obtained.

Let's assume you want to do gaussian density estimation, based on the example of scipy.stats.gaussian_kde, you can get the density height with:

def density_estimation(m1, m2):
    X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]                                                     
    positions = np.vstack([X.ravel(), Y.ravel()])                                                       
    values = np.vstack([m1, m2])                                                                        
    kernel = stats.gaussian_kde(values)                                                                 
    Z = np.reshape(kernel(positions).T, X.shape)
    return X, Y, Z

Then, you can plot it with contour with

X, Y, Z = density_estimation(m1, m2)

fig, ax = plt.subplots()                   

# Show density 
ax.imshow(np.rot90(Z), cmap=plt.cm.gist_earth_r,                                                    
          extent=[xmin, xmax, ymin, ymax])

# Add contour lines
plt.contour(X, Y, Z)                                                                           

ax.plot(m1, m2, 'k.', markersize=2)    

ax.set_xlim([xmin, xmax])                                                                           
ax.set_ylim([ymin, ymax])                                                                           
plt.show()

As an alternative, you could change the marker color based on their density as shown here.