Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

All text is lost when using openGL renderer in batch mode

When running MATLAB in a batch mode without a display (e.g. with the $DISPLAY UNIX environment variable unset, or with the matlab -nodisplay flag at startup), normally you cannot use the opengl renderer. Instead you must settle for the painters renderer. For example:

>> print -dpng -opengl fig.png
Warning: OpenGL mode can not be used in terminal emulation mode; ignoring option. 

Unfortunately, painters often gives poor results when working with 3D scenes with patches, lighting, transparency, etc.. Here is one simple example (using a display for now) where the alpha is lost:

peaks
alpha(0.5)
print -dpng -opengl peaks_opengl.png
print -dpng -painters peaks_painters.png

enter image description here


Because of these limitations, I was very excited to find the mostly-undocumented hardcopy() built-in MATLAB function, which does somehow let you use the opengl renderer without a display. This function underlies the terrific export_fig() function. Now I am able to very rapidly save high quality 3D figures in batch mode.

However, there is one catch: All text is lost when the figure gets passed through the hardcopy() function. For example:

plot(1,1)
title('TEST')
>> A = hardcopy(gcf, '-Dopengl', '-r300');
Warning: Failed to draw text string
> In /Applications/MATLAB_R2010b.app/toolbox/matlab/graphics/hardcopy.p>hardcopy at 21

The output figure is completely lacking any text (no axis ticks labels and no title):

export_fig axis.png -opengl

enter image description here

So what I'm wondering is: How can I get the opengl renderer to work with text in batch mode? Is there a way I can get text to work with the hardcopy() function? Perhaps a way to rasterize the text beforehand? Or a way to combine a painters hardcopy of the text and an opengl hardcopy of the plot? Alternatively, is there a completely different route to make this work than the hardcopy() function? Also note that the problem is unlikely to be with my system setup, since it is reproducible under both Mac OS and Ubuntu.

like image 921
John Colby Avatar asked Feb 18 '12 01:02

John Colby


1 Answers

If you're using Linux, you can use a software OpenGL renderer (modern versions of Matlab have one bundled). Such an option does not exist for Mac OS, at least not with current Matlab versions. Windows is easy - even the batch mode runs a display, so you can work as usual.

  1. Run Xvfb :1 &, which creates a (virtual) framebuffer X server.
  2. Prepare your code in some file, say bla.m :

    opengl software;
    peaks
    alpha(0.5);
    print -dpng -opengl peaks_opengl.png
    exit
    

    It's very important not to forget opengl software, as you imagine.

  3. Run the following command:

    cat bla.m | matlab -display :1 -logfile log.txt
    

    which makes Matlab execute whatever's in bla.m, on the virtual display, and writes whatever Matlab outputs into log.txt. You can drop the logfile when everything seems to be working. Also, note that :display :1 has to fit the number you provided in the Xvfb invocation.

  4. Profit.

like image 94
user1071136 Avatar answered Sep 22 '22 13:09

user1071136