4
votes

I would like to draw a 3D carpet plot with Python Pylab or matplotlib. I explain what I mean with carpet plot:

I have points on a X,Y meshgrid. This points have an elevation attached to them, but also an integer from a finite set. A common 3D plot makes it possible to vizualize relief. Elevation is along Z, we can vizualize elevation for a points determined by its coordinates X,Y along Z-axis. Alternatively, I draw heatmaps for elevation. It is a 2D plot, each pixel determined by X,Y has a color that is a function of altitude, red for apex and blue for bottom. I do some clustering on these data, and after clustering, I have, for each pixel, two information: elevation and a label (integer). I can draw a 2D map with each pixel colored with its label, and this gives me the clustering results.

Now, I would like to plot both information on same 3D graph. Z coordinate should be elevation, and the point on surface should be colored with its "cluster color". This is what I call the 3D carpet plot (if term does not sound correct, please tell me).

1

1 Answers

3
votes

Your "cluster color" is some set of conditions on the X,Y,Z values of your grid. If you can make these a mask (of True/False values) it is simple to map a color onto them. I've given an example of an arbitrary set of conditions, which you can adapt to your needs. Code was adapted from http://matplotlib.sourceforge.net/mpl_toolkits/mplot3d/tutorial.html:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

# Some sample data
x_side = np.arange(-5, 5, 0.04)
y_side = np.arange(-5, 5, 0.04)
X, Y = np.meshgrid(x_side,y_side)

# Fake mountains
Z = np.exp(-(X**2+Y**2)) + 2*np.exp(-((X-2)**2+Y**2)) 

# Assign colors based off some user-defined condition
COLORS = np.empty(X.shape, dtype=str)
COLORS[:,:] = 'b'
COLORS[(Z>.1) * (Z<.3)] = 'r'
COLORS[Z>.3] = 'g'
COLORS[X+Y < -1] = 'k'

# 3D surface plot
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, Z, facecolors=COLORS, rstride=1, cstride=1,
        linewidth=0)
plt.show()

enter image description here