8

I have some 2D data that I am displaying using pcolormesh that I would like to display a few contours on top of. I create the gridded data using

import numpy as np
import matplotlib.pyplot as plt

def bin(x, y, nbins, weights=None):
    hist, X, Y = np.histogram2d(x, y, bins=nbins, weights=weights)
    x_grid, y_grid = np.meshgrid(X,Y)
    return hist, x_grid, y_grid

data = ... # read from binary file
h,x_grid,y_grid = bin(data.x,data.y,512)
# do some calculations with h
h = masked_log(h) # "safe" log that replaces <0 elements by 0 in output

pcm = plt.pcolormesh(x_grid,y_grid,h,cmap='jet')

# Just pretend that the data are lying on the center of the grid
# points, rather than on the edges
cont = plt.contour(x_grid[0:-1,0:-1],y_grid[0:-1,0:-1],h,4,colors='k',origin='lower')

When I plot only the output of pcolormesh, everything looks great. Adding the contours makes a giant mess.


I have read through the contour demo, the API examples, the pcolormesh levels example, and this closely-related SO post (my data is already gridded, so the solution doesn't help). But nothing I have tried thus far has created 4 simple contour lines atop my pcolormesh data.

Community
  • 1
  • 1
Tim
  • 1,517
  • 1
  • 9
  • 15
  • It looks like your data is pretty noisy which is probably why contour does not looks as desired. You could try smoothing your data before using contour plot. Manually specify levels, e.g. `levels = np.linspace(-4, 6, 4)` for `plt.contour(... , levels = levels)` may also help... I suggest uploading your data to provide a minimum example so people can help. – Ed Smith Dec 21 '15 at 14:52
  • @EdSmith, I forgot to mention that I had tried specifying my own contour levels, as well, without any luck. I can't upload my data as it is proprietary at the moment (it's also 4GB). – Tim Dec 22 '15 at 23:18

1 Answers1

11

I've put together minimal example with Gaussian filter (and scipy) which I think looks like it may do what you want. First, set up some dummy data (a Gaussian) and add noise,

import matplotlib
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z += 0.1*np.random.random(Z.shape)

and try to pcolormesh/contour,

plt.figure()
CS = plt.pcolormesh(X, Y, Z)
plt.contour(X, Y, Z, 4, colors='k')
plt.colorbar(CS)
plt.show()

which looks like this,

enter image description here

If we add filtering as follows,

import matplotlib
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
from scipy.ndimage.filters import gaussian_filter

delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z += 0.1*np.random.random(Z.shape)

plt.figure()
plt.pcolormesh(X, Y, Z)

CS = plt.contour(X, Y, gaussian_filter(Z, 5.), 4, colors='k',interpolation='none')
plt.colorbar()
plt.show()

it looks much better,enter image description here

Ed Smith
  • 12,716
  • 2
  • 43
  • 55
  • 1
    This was exactly the problem! I was going out of my mind thinking I had done something procedurally incorrect, but it was just noisy data. – Tim Dec 22 '15 at 23:19