0

I am using this code:

z = np.asarray(image_list)
mydata = z[::1,::1]
fig = pl.figure(facecolor='w')

ax2 = fig.add_subplot(1,1,1,projection='3d')
x,y = np.mgrid[:mydata.shape[0],:mydata.shape[1]]
ax2.plot_surface(x,y,mydata,cmap=pl.cm.jet,rstride=1,cstride=1,linewidth=0.,antia liased=False)
ax2.set_title('3D')
ax2.set_zlim3d(0,200)
pl.show()

To plot a 3D image using a list containing a set of images, but I get this error:

Traceback (most recent call last):
ax2.plot_surface(x,y,mydata,cmap=pl.cm.jet,rstride=1,cstride=1,linewidth=0.,antialiased=False)

File "/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py", line 1553, in plot_surface 
X, Y, Z = np.broadcast_arrays(X, Y, Z)

File "/usr/lib/python2.7/dist-packages/numpy/lib/stride_tricks.py", line 100, in broadcast_arrays 
"incompatible dimensions on axis %r." % (axis,))

ValueError: shape mismatch: two or more arrays have incompatible dimensions on axis 2

Could anyone help me with this error or suggest some other technique to create a 3D image from a image list containing 2D images?

prinks
  • 11
  • 4
  • Maybe these two questions can shed some light: [Plot iso-surface with mayavi/VTK](http://stackoverflow.com/q/6030098/2379410) and [**Calculate** and plot 3D iso-surface](http://stackoverflow.com/q/13627104/2379410). –  Jul 18 '15 at 10:20

1 Answers1

0

I can't remember where I found this exactly (it was another StackOverflow thread), but this is working code - yours looks like a sample of the one I have - just change out the filename to load:

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pylab as pl
from PIL import Image
import numpy as np
import pylab

img = Image.open('natureWallpaper.jpg').convert('L')
z   = np.asarray(img)
#slice notation: "start:stop:step" - here it's referring to the z matrix's x and y dimensions, get the whole of each
mydata = z[::1,::1]
fig = pl.figure(facecolor='w')
# subplot(nrows, ncols, plotnumber)
ax1 = fig.add_subplot(1,2,1)
# im = ax1.imshow(mydata,interpolation='nearest',cmap=pl.cm.jet)
im = ax1.imshow(mydata,interpolation='none',cmap=pl.cm.jet)
ax1.set_title('2D')

ax2 = fig.add_subplot(1,2,2,projection='3d')
x,y = np.mgrid[:mydata.shape[0],:mydata.shape[1]] ax2.plot_surface(x,y,mydata,cmap=pl.cm.jet,rstride=10,cstride=10,linewidth=0.antialiased=False)
ax2.set_title('3D')
ax2.set_zlim3d(0,255)
pl.show()
JakeJ
  • 2,361
  • 5
  • 23
  • 35
  • This does one image at a time. If you want an image list, I suppose you could always put all of that in a function, then feed that function a series of filenames or something like that. The graph is a bit slow on large images, so you'd need a way to grab input before loading the next one. – JakeJ Jul 18 '15 at 04:40
  • It looks like your image list line is really throwing a wrench in things. – JakeJ Jul 18 '15 at 04:45
  • The problem is that pl.show() is meant to show one image at a time. There might be a way to put a few images side by side. If I do it this weekend, I'll come back here and put that code up as well. – JakeJ Jul 18 '15 at 05:47
  • Ah, check out the bottom comment here: https://stackoverflow.com/questions/29620874/matplotlib-show-multiple-images-with-for-loop ...apparently if you increment figure inside of a for loop / call pl.show() outside, you'll have a plot for each image you load. – JakeJ Jul 18 '15 at 05:52
  • Here was where I got the original code from: https://stackoverflow.com/questions/15581935/python-3d-contour-from-a-2d-image-pylab-and-contourf – JakeJ Jul 18 '15 at 06:17