I have a series of basic 2D images (3 for simplicity for now) and these are related to each other, analogous to frames from a movie:
Within python how may I stack the
Here is a completely silly way to accomplish using matplotlib and shear transformations (you probably need to tweak the transform matrix some more so the stacked images look correct):
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage.interpolation import affine_transform
nimages = 4
img_height, img_width = 512, 512
bg_val = -1 # Some flag value indicating the background.
# Random test images.
rs = np.random.RandomState(123)
img = rs.randn(img_height, img_width)*0.1
images = [img+(i+1) for i in range(nimages)]
stacked_height = 2*img_height
stacked_width = img_width + (nimages-1)*img_width/2
stacked = np.full((stacked_height, stacked_width), bg_val)
# Affine transform matrix.
T = np.array([[1,-1],
[0, 1]])
for i in range(nimages):
# The first image will be right most and on the "bottom" of the stack.
o = (nimages-i-1) * img_width/2
out = affine_transform(images[i], T, offset=[o,-o],
output_shape=stacked.shape, cval=bg_val)
stacked[out != bg_val] = out[out != bg_val]
plt.imshow(stacked, cmap=plt.cm.viridis)
plt.show()
As far as I know, matplotlib has no 3D equivalent to imshow
that would allow you to draw a 2D array as a plane within 3D axes. However, mayavi seems to have exactly the function you're looking for.
You can't do this with imshow, but you can with contourf, if that will work for you. It's a bit of a kludge though:
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
x = np.linspace(0, 1, 100)
X, Y = np.meshgrid(x, x)
Z = np.sin(X)*np.sin(Y)
levels = np.linspace(-1, 1, 40)
ax.contourf(X, Y, .1*np.sin(3*X)*np.sin(5*Y), zdir='z', levels=.1*levels)
ax.contourf(X, Y, 3+.1*np.sin(5*X)*np.sin(8*Y), zdir='z', levels=3+.1*levels)
ax.contourf(X, Y, 7+.1*np.sin(7*X)*np.sin(3*Y), zdir='z', levels=7+.1*levels)
ax.legend()
ax.set_xlim3d(0, 1)
ax.set_ylim3d(0, 1)
ax.set_zlim3d(0, 10)
plt.show()
The docs of what's implemented in 3D are here.
As ali_m suggested, if this won't work for you, if you can imagine it you can do it with VTk/MayaVi.