Python: построить 3D-форму поверх 2D-изображения

Я пытаюсь построить трехмерную фигуру с двухмерным изображением, накладывающим плоскость xy. Я только начал работать с python, так что это сложнее, чем должно быть.

Этот вопрос здесь касается того, что я пытаюсь сделать: Наложение изображения в 3D-графике с использованием python . Но когда я запускаю предоставленный код, я получаю следующую ошибку:

File "test.py", line 13, in <module>
ax.plot_surface(x, y, 10, rstride=5, cstride=5, facecolors=img)
File "/usr/lib64/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 663, in plot_surface
rows, cols = Z.shape
AttributeError: 'int' object has no attribute 'shape'

Изображение, которое я использую, хранится в той же папке, что и мой «test.py». В вопросе, на который я ссылался выше, используется изображение из get_sample_data, но если я отредактирую его, чтобы использовать свое изображение, код будет следующим:

from pylab import *
from mpl_toolkits.mplot3d import Axes3D
from matplotlib._png import read_png

img = read_png('milkyway.png')

x, y = ogrid[0:img.shape[0], 0:img.shape[1]]
ax = gca(projection='3d')
ax.plot_surface(x, y, 10, rstride=5, cstride=5, facecolors=img)
show()

Я получаю ту же ошибку, использую ли я get_sample_data или собственное изображение. Любые предложения о том, что я могу изменить? Спасибо!


person user2569840    schedule 10.07.2013    source источник
comment
Можете ли вы обновить свою версию mpl? Этот код корректно работает с более новыми версиями библиотеки.   -  person tacaswell    schedule 11.07.2013
comment
Боюсь, что нет, я делаю это на работе (университетские компьютеры).   -  person user2569840    schedule 11.07.2013
comment
вы всегда можете установить локальную версию mpl.   -  person tacaswell    schedule 11.07.2013


Ответы (2)


Ошибка, по-видимому, связана с тем, что plot_surface ожидает массив для аргумента «Z», но вы дали ему целое число 10. (таким образом, объект ошибки «int» не имеет атрибута «форма»)

person Luke    schedule 10.07.2013
comment
Я хочу поместить изображение в z = 0, поэтому могу ли я сделать z массивом из 0? Если это так, и он должен быть того же размера, что и x и y, могу ли я написать: z = np.zeros(size(x))? - person user2569840; 11.07.2013
comment
Ознакомьтесь с документацией по API: matplotlib.org/mpl_toolkits/ mplot3d/ Каждый аргумент представляет собой двумерный массив, предоставляющий координаты x, y или z сетки точек. - person Luke; 11.07.2013
comment
@ user2569840 Это правильная идея, но она должна быть z = np.zeros(x.shape) - person tacaswell; 11.07.2013

Вы неправильно загружаете свое изображение - read_png() нужен файловый объект в качестве входных данных, а не путь к файлу. Попробуй это:

 f = open('milkyway.png','r')
 img = read_png(f)
person ali_m    schedule 10.07.2013
comment
Хорошо, как выглядит img? Это определенно массив rows x cols x RGB(A)? Можете ли вы просто imshow это? - person ali_m; 11.07.2013
comment
Да, imshow прекрасно это показывает. Хитрость теперь заключается в том, чтобы превратить его в трехмерный сюжет. - person user2569840; 11.07.2013
comment
Теперь x и y просто должны быть двумерными массивами той же формы, что и изображение. В моей версии matplotlib (1.2.1) plot_surface, кажется, принимает целочисленный аргумент для z, но если это не сработает, вы также должны попробовать передать ему массив той же формы, что и x и y: z = np.zeros_like(x). - person ali_m; 11.07.2013