I got another idea: did you take into account that your stencil, in order to approximate the Laplacian, should be divided by step**2, where step is the step size of your grid? Only then can you compare the ndimage.convolve result with the analytical result.
In fact, with a Gaussian, I obtain results that indicate that ndimage.convolve works quite well:
from scipy import ndimage
stencil = numpy.array([[0, 1, 0],[1, -4, 1], [0, 1, 0]])
x = linspace(-10, 10, 100)
y = linspace(-10, 10, 100)
xx, yy = meshgrid(x, y)
image = exp(-xx**2-yy**2) # Standard deviation in x or y: 1/sqrt(2)
laplaced = ndimage.convolve(image, stencil)/(x[1]-x[0])**2 # stencil from original post
expected_result = -4*image + 8*(xx**2+yy**2)*image # Very close to laplaced, in most points!