enthought / mayavi

3D visualization of scientific data in Python
http://docs.enthought.com/mayavi/mayavi/
Other
1.3k stars 285 forks source link

mlab.screenshot() ValueError #702

Closed xyloid closed 6 years ago

xyloid commented 6 years ago

After I installed mayavi-4.6.1 using pip, I tried the following program:

from mayavi import mlab
mlab.test_plot3d()
arr = mlab.screenshot()
import pylab as pl
pl.imshow(arr)
pl.axis('off')
pl.show()

and then got this error:

C:\Users\xyloid\Anaconda3\python.exe C:/Users/xyloid/source/TrySnippet.py
Traceback (most recent call last):
  File "C:/Users/xyloid/source/TrySnippet.py", line 3, in <module>
    arr = mlab.screenshot()
  File "C:\Users\xyloid\Anaconda3\lib\site-packages\mayavi\tools\figure.py", line 352, in screenshot
    out.shape = shape
ValueError: cannot reshape array of size 12 into shape (0,0,3)

Process finished with exit code 1

I searched with google but could not find any similiar error. When I printed out.shape and shape, I got (4,3) and (0,0,3). Then I am confused, I don't know why x, y = tuple(figure.scene.render_window.size) get (0,0) as I did see a figure before this error. What is the problem? Is there anything wrong in tvtk.RenderWindow? Thanks in advance!

prabhuramachandran commented 6 years ago

Works for me, although I suspect this because of the UI mainloop and events not being processed in order to make the window of a suitable size. Try this:

from mayavi import mlab
mlab.test_plot3d()
mlab.process_ui_events()
arr = mlab.screenshot()
import pylab as pl
pl.imshow(arr)
pl.axis('off')
pl.show()

Only change is the process_ui_events call.

xyloid commented 6 years ago

@prabhuramachandran Thank you for your help. I tried your code but still got the same error. Since I found out that this error only appeared on the first time screenshot() is called, I think your assumption makes sense. Then I looked into figure.py to find something after x, y = tuple(figure.scene.render_window.size) that made the difference. Then I found the following code works for me.

from mayavi import mlab
mlab.test_plot3d()
f = mlab.gcf()
f.scene._lift()
arr = mlab.screenshot()
import pylab as pl
pl.imshow(arr)
pl.axis('off')
pl.show()
prabhuramachandran commented 6 years ago

I am closing this issue for now as I am not sure this is really an issue any more? Do let me know if you wish to reopen it.

rjp23 commented 5 years ago

Every single tutorial I've tried following has been giving me the same error.

This solved it:

f = mlab.gcf()
f.scene._lift()

Thanks!

prabhuramachandran commented 5 years ago

@rjp23 -- If you are running this without a mainloop you will get this, you must generally run a GUI mainloop, on IPython, use %gui qt and that should fix the issues. If you do not want to do that and still make this work then we need to add something to make this easier rather than your current solution.

tom-wood commented 5 years ago

Just to say that I also see this issue using mayavi-4.6.1 (on Windows 10, installed from conda-forge with IPython 7.1.1 and qt 5.6.2). Running %gui qt or similar makes no difference, but

f = mlab.gcf()
f.scene._lift()

as detailed above works well.

lopsided commented 2 years ago

Confirming this is still an issue when calling screenshot from a script without the gui. Version 4.7.4. The suggested fix still works though.

giammi56 commented 1 year ago

I confirm it is still an issue too. If I run in in debug mode (VSCode), it works, though!

Example:

import numpy as np
import mayavi.mlab as mlab

duration= 2 # duration of the animation in seconds (it will loop)

fig_myv = mlab.figure(size=(220,220), bgcolor=(1,1,1))
X, Y = np.linspace(-2,2,200), np.linspace(-2,2,200)
XX, YY = np.meshgrid(X,Y)
ZZ = lambda d: np.sinc(XX**2+YY**2)+np.sin(XX+d)

def make_frame(t):
    mlab.clf() # clear the figure (to reset the colors)
    mlab.mesh(YY,XX,ZZ(2*np.pi*t/duration), figure=fig_myv)
    return mlab.screenshot(antialiased=True)

make_frame(1)