How to plot multiple regression 3D plot in python
Question: I am not a scientist, so please assume that I do not know the jargon of
experienced programmers, or the intricacies of scientific plotting techniques.
Python is the only language I know (beginner+, maybe intermediate).

**Task** : Plot the results of a multiple regression (z = f(x, y) ) as a two
dimensional plane on a 3D graph (as I can using OSX’s graphing utility, for
example, or as implemented here [Plot Regression
Surface](http://stackoverflow.com/questions/7863906/plot-regression-surface)
with R).

After a week searching **Stackoverflow** and reading various documentations of
**matplotlib** , **seaborn** and **mayavi** I finally found [Python the
simplest way to plot 3d
surface](http://stackoverflow.com/questions/12423601/python-the-simplest-way-
to-plot-3d-surface/25586869#25586869) which sounded promising. So here is my
data and code:

**_First try with matplotlib:_**

    
    
    shape: (80, 3) 
    type: <type 'numpy.ndarray'> 
    zmul: 
    
    [[  0.00000000e+00   0.00000000e+00   5.52720000e+00]
     [  5.00000000e+02   5.00000000e-01   5.59220000e+00]
     [  1.00000000e+03   1.00000000e+00   5.65720000e+00]
     [  1.50000000e+03   1.50000000e+00   5.72220000e+00]
     [  2.00000000e+03   2.00000000e+00   5.78720000e+00]
     [  2.50000000e+03   2.50000000e+00   5.85220000e+00]
     ……]
    
    import matplotlib
    from matplotlib.ticker import MaxNLocator
    from matplotlib import cm
    
    from numpy.random import randn
    from scipy import array, newaxis
    Xs = zmul[:,0]
    Ys = zmul[:,1]
    Zs = zmul[:,2]
    
    
    surf = ax.plot_trisurf(Xs, Ys, Zs, cmap=cm.jet, linewidth=0)
    fig.colorbar(surf)
    
    ax.xaxis.set_major_locator(MaxNLocator(5))
    ax.yaxis.set_major_locator(MaxNLocator(6))
    ax.zaxis.set_major_locator(MaxNLocator(5))
    
    fig.tight_layout()
    
    plt.show()
    

All I get is an empty 3D coordinate frame with the following error message:

RuntimeError: Error in qhull Delaunay triangulation calculation: singular
input data (exitcode=2); use python verbose option (-v) to see original qhull
error.

I tried to see if I could play around with the plotting parameters and checked
this site <http://www.qhull.org/html/qh-impre.htm#delaunay>, but I really
cannot make sense of what I am supposed to do.

**_Second try with mayavi:_**

Same data, divided into 3 numpy arrays:

    
    
    type: <type 'numpy.ndarray'> 
    X: [    0   500  1000  1500  2000  2500  3000 ….]
    
    type: <type 'numpy.ndarray'> 
    Y: [  0.    0.5   1.    1.5   2.    2.5   3.  ….]
    
    type: <type 'numpy.ndarray'> 
    Z: [  5.5272   5.5922   5.6572   5.7222   5.7872   5.8522   5.9172  ….] 
    

Code:

    
    
    from mayavi import mlab
    def multiple3_triple(tpl_lst):
    
    X = xs
    Y = ys
    Z = zs
    
    
    # Define the points in 3D space
    # including color code based on Z coordinate.
    pts = mlab.points3d(X, Y, Z, Z)
    
    # Triangulate based on X, Y with Delaunay 2D algorithm.
    # Save resulting triangulation.
    mesh = mlab.pipeline.delaunay2d(pts)
    
    # Remove the point representation from the plot
    pts.remove()
    
    # Draw a surface based on the triangulation
    surf = mlab.pipeline.surface(mesh)
    
    # Simple plot.
    mlab.xlabel("x")
    mlab.ylabel("y")
    mlab.zlabel("z")
    mlab.show()
    

All I get is this:

[![enter image description
here](http://i.stack.imgur.com/7MNcs.png)](http://i.stack.imgur.com/7MNcs.png)

If this matters, I am using the 64 bit version of Enthought's Canopy on OSX
10.9.3

Will be grateful for any input on what I am doing wrong.

EDIT: Posting the final code that worked, in case it helps someone.

    
    
    '''After the usual imports'''
    def multiple3(tpl_lst):
        mul = []
        for tpl in tpl_lst:
            calc = (.0001*tpl[0]) + (.017*tpl[1])+ 6.166
            mul.append(calc)
        return mul
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    '''some skipped code for the scatterplot'''
    X = np.arange(0, 40000, 500)
    Y = np.arange(0, 40, .5)
    X, Y = np.meshgrid(X, Y)
    Z = multiple3(zip(X,Y))
    
    surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,cmap=cm.autumn,
                           linewidth=0, antialiased=False, alpha =.1)
    ax.set_zlim(1.01, 11.01)
    ax.set_xlabel(' x = IPP')
    ax.set_ylabel('y = UNRP20')
    ax.set_zlabel('z = DI')
    
    ax.zaxis.set_major_locator(LinearLocator(10))
    ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
    fig.colorbar(surf, shrink=0.5, aspect=5)
    plt.show()
    

[![enter image description
here](http://i.stack.imgur.com/ABq81.png)](http://i.stack.imgur.com/ABq81.png)


Answer: for matplotlib, you can base off the [surface
example](http://matplotlib.org/examples/mplot3d/surface3d_demo.html) (you're
missing plt.meshgrid):

    
    
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    from matplotlib.ticker import LinearLocator, FormatStrFormatter
    import matplotlib.pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    X = np.arange(-5, 5, 0.25)
    Y = np.arange(-5, 5, 0.25)
    X, Y = np.meshgrid(X, Y)
    R = np.sqrt(X**2 + Y**2)
    Z = np.sin(R)
    surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
                           linewidth=0, antialiased=False)
    ax.set_zlim(-1.01, 1.01)
    
    ax.zaxis.set_major_locator(LinearLocator(10))
    ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
    
    fig.colorbar(surf, shrink=0.5, aspect=5)
    
    plt.show()
    

