Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number density contours in Python

I'm trying to reproduce this plot in python with little luck:

enter image description here

It's a simple number density contour currently done in SuperMongo. I'd like to drop it in favor of Python but the closest I can get is:

enter image description here

which is by using hexbin(). How could I go about getting the python plot to resemble the SuperMongo one? I don't have enough rep to post images, sorry for the links. Thanks for your time!

like image 608
Robert Avatar asked Jul 15 '11 05:07

Robert


1 Answers

Example simple contour plot from a fellow SuperMongo => python sufferer:

import numpy as np
from matplotlib.colors import LogNorm
from matplotlib import pyplot as plt

plt.interactive(True)
fig=plt.figure(1)
plt.clf()

# generate input data; you already have that
x1 = np.random.normal(0,10,100000)
y1 = np.random.normal(0,7,100000)/10.
x2 = np.random.normal(-15,7,100000)
y2 = np.random.normal(-10,10,100000)/10.
x=np.concatenate([x1,x2])
y=np.concatenate([y1,y2])

# calculate the 2D density of the data given
counts,xbins,ybins=np.histogram2d(x,y,bins=100,normed=LogNorm())
# make the contour plot
plt.contour(counts.transpose(),extent=[xbins.min(),xbins.max(),
    ybins.min(),ybins.max()],linewidths=3,colors='black',
    linestyles='solid')
plt.show()

produces a nice contour plot.

The contour function offers a lot of fancy adjustments, for example let's set the levels by hand:

plt.clf()
mylevels=[1.e-4, 1.e-3, 1.e-2]
plt.contour(counts.transpose(),mylevels,extent=[xbins.min(),xbins.max(),
    ybins.min(),ybins.max()],linewidths=3,colors='black',
    linestyles='solid')
plt.show()

producing this plot:contour plot with adjusted levels

And finally, in SM one can do contour plots on linear and log scales, so I spent a little time trying to figure out how to do this in matplotlib. Here is an example when the y points need to be plotted on the log scale and the x points still on the linear scale:

plt.clf()
# this is our new data which ought to be plotted on the log scale
ynew=10**y
# but the binning needs to be done in linear space
counts,xbins,ybins=np.histogram2d(x,y,bins=100,normed=LogNorm())
mylevels=[1.e-4,1.e-3,1.e-2]
# and the plotting needs to be done in the data (i.e., exponential) space
plt.contour(xbins[:-1],10**ybins[:-1],counts.transpose(),mylevels,
    extent=[xbins.min(),xbins.max(),ybins.min(),ybins.max()],
    linewidths=3,colors='black',linestyles='solid')
plt.yscale('log')
plt.show()

This produces a plot which looks very similar to the linear one, but with a nice vertical log axis, which is what was intended: contour plot with log axis

like image 87
AlinaZ Avatar answered Sep 24 '22 05:09

AlinaZ