3D histograms and Contour plots Python
Question: I have a problem with contourf function of matplotlib. I have a txt data file
from which I am importing my data. I have columns of data (pm1 and pm2) and I
am performing a 2D histogram. I want to plot this data as a 3D histogram and
as a contour plot to see where is located the maximum values.

This is my code:

    
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    rows = np.arange(200,1300,10)
    
    hist, xedges, yedges = np.histogram2d (pm1_n, pm2_n, bins = (rows, rows) )
    elements = (len(xedges) - 1) * (len(yedges) - 1)
    
    
    xpos, ypos = np.meshgrid(xedges[:-1], yedges[:-1])
    
    xpos = xpos.flatten()
    ypos = ypos.flatten()
    zpos = np.zeros(elements)
    dx = 0.1 * np.ones_like(zpos)
    dy = dx.copy()
    dz = hist.flatten()
    
    #####The problem is here#####
    
    #ax.contourf(xpos,ypos,hist)
    #ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average')
    
    plt.show()
    

I can plot the 3d bar graph but I am not able to plot the contour one, If I
place `hist` in the contourf function I get the error: `Length of x must be
number of columns in z` and if I place `dz` I get `Input z must be a 2D array`
I also have tried using xedges and yexges but this doesn't solve the problem.

I think that the problem is related with the shape of the return of the
function histogram2D. But I don't know how to solve it.

I would also like to perform a 3D bar plot with a colorcode changing form the
minimum to the maximum value. Is there anyway to make this?

Thank you


Answer: Perhaps I don't understand what exactly you are trying to do since I don't
know what your data looks like, but it seems wrong to have your `contourf`
plot sharing the same axis as your `bar3d` plot. If you add an axis without
the 3D projection to a new figure, you should be able to make a `contourf`
plot just fine using `hist`. An example using data from a random, normal
distribution:

    
    
    import numpy as np
    import matplotlib.pyplot as plt
    
    n_points = 1000
    x = np.random.normal(0, 2, n_points)
    y = np.random.normal(0, 2, n_points)
    
    hist, xedges, yedges = np.histogram2d(x, y, bins=np.sqrt(n_points))
    
    fig2D = plt.figure()
    ax2D = fig2D.add_subplot(111)
    ax2D.contourf(hist, interpolation='nearest', 
                  extent=(xedges[0], xedges[-1], yedges[0], yedges[-1]))
    plt.show()
    

returns an image like [this](http://i.stack.imgur.com/u2JZ0.png).

As for your second question, regarding a color-coded 3D bar plot, how about
this (using the same data as above but with 1/10 the size):

    
    
    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    import matplotlib.colors as colors
    
    n_points = 100
    x = np.random.normal(0, 2, n_points)
    y = np.random.normal(0, 2, n_points)
    
    hist, xedges, yedges = np.histogram2d(x, y, bins=np.sqrt(n_points))
    
    # Following your data reduction process
    xpos, ypos = np.meshgrid(xedges[:-1], yedges[:-1])
    
    length, width = 0.4, 0.4
    xpos = xpos.flatten()
    ypos = ypos.flatten()
    zpos = np.zeros(n_points)
    dx = np.ones(n_points) * length
    dy = np.ones(n_points) * width
    dz = hist.flatten()
    
    # This is where the colorbar customization comes in
    dz_normed = dz / dz.max()
    normed_cbar = colors.Normalize(dz_normed.min(), dz_normed.max())
    # Using jet, but should work with any colorbar
    color = cm.jet(normed_cbar(dz_normed))
    
    fig3D = plt.figure()
    ax3D = fig3D.add_subplot(111, projection='3d')
    ax3D.bar3d(xpos, ypos, zpos, dx, dy, dz, color=color)
    plt.show()
    

I get [this image](http://i.stack.imgur.com/D9Pst.png).

