The problem with octave(matlab). In the program I have loop where I plot data. In the end of each loop I save plots to disc. During this process octave draw each plot. It slows down the process. I need only plots to be saved on disc. If I could not display them,but just save, it would considerably accelerate the process. Is there way to draw plot to handler without displaying it? to draw I use scatter function.
This is not tested with matlab, and potentially only limited to octave.
Using f = figure('visible','off') will not work out of the box.
You need to select a proper graphics toolkit:
available_graphics_toolkits
ans =
{
[1,1] = fltk
[1,2] = gnuplot
}
The default is fltk which cannot write to file without displaying the plot. However, if you select gnuplot it will be able to write to file without displaying it first:
graphics_toolkit gnuplot
f = figure('visible','off')
plot(...)
axis(...)
filename=sprintf('output/%05d.png',t);
print(filename);
It is not particularly fast, but it doesn't use screen buffers or captures the mouse, which happens if the plot needs to be visible.
As answered in this question, I would do:
f = figure('visible','off')
Offscreen rendering is supported on GNU/Linux since GNU Octave 4.0 using OSMesa. So today there are basically two ways to get figure ("visible", "off");... print (...)working:
If you not have a proprietary OpenGL driver but a MESA based driver like radeon, nouveau and so on (basically all free (as in freedom) drivers are based on Mesa) you can use OpenGL based toolkits (qt, fltk) and Octave will use OSMesa for printing.
Using gnuplot: graphics_toolkit gnuplot as said before
Related
I need some to produce some publication-quality figures. I first export the figures from matlab in .svg format, and then I do some post-processing in inkscape. I am no problem with figures generated using plot or scatter, but when I export figures generated using surf (in view(2)), I run into problems. If I use plot or scatter, I am able to ungroup and process various parts like the title, axes, scattered points, lines, etc. in inkscape. For surf, however, matlab just exports one single figures with all various parts grouped into one single unit. I can't separate individual part, and when I zoom very close I can actually see the bitmap resolution for the axes and titles (if I use plot, the titles and axes have 'infinite' resolution when I zoom very close). I am fine with the surface plot having finite resolution, but I need to at least be able to process the axes and titles (which I currently cannot do). What should I do so that I can 'separate' the title and axes from the main plot, just like figures generated from plot and scatter?
I stumbled across this question, since I encountered the same problem.
As mentioned by #vindarmagnus, it is possible to use tikz and get rather nice results. However, tikz experiences problems with large data sets in my experience as present when using surf etc..
Solution, that worked for me:
Change the renderer to painters and the exported .svg file will retain its vectorgraphic properties when opened e.g. in inkscape:
figure('Renderer','Painters');
I used to use Inkscape for my scientific publications as well, but I found that a lot of the time you can get better results with pgfplots in latex, together with the matlab2tikz matlabscript. There’s a ton of resources about this online, but here’s how my workflow would look adopted to your surf situation. I have macOSX with latex, matlab and matlab2tikz installed. Will work with little to no modifications on linux.
In Matlab:
surf(peaks(25))
matlab2tikz('plot.tikz’)
Then I have the following bash-script (just a script in the same folder as the image, which is executed by mere double-click). (Needs to be chmod-ed as an executable for that).
#!/bin/bash
cd ~/Desktop
rm *.eps
cat > plot.tex << EOF
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{max space between ticks=50}
\pgfplotsset{scaled ticks = false}
\pgfplotsset{compat=1.6}
\pgfplotsset{xticklabel style={/pgf/number format/fixed}}
\pgfplotsset{yticklabel style={/pgf/number format/fixed}}
\begin{document}
\input{plot.tikz}
\end{document}
EOF
pdflatex plot.tex
pdf2ps plot.pdf
ps2eps plot.ps
Note that the row cd ~/Desktop above should be changed as to reflect which folder the script is supposed to be run from (a bit crappy, but needed since Finder doesn’t properly pass along the folder from a program is executed, afaik).
This yields high-quality images in eps or pdf or what you like, with a ton of settings for axes and ticks etc. And it all uses native latex fonts.
Edit:
Recently I’ve begun to use patch() in matlab and then export it to tikz in the same manner as above, with great results. That’s another suggestion!
You can use also:
set(gcf,'Renderer','Painters')
I'm currently using the Matlab/Octave online IDE at http://www.tutorialspoint.com/execute_matlab_online.php and I'm trying to save a graph that I'm plotting to .pdf format. I've done the following:
- octave
- x = [ 1: 10 ]
- y = x
- plot(x,y)
- print -dpdf graph.pdf
I then refresh the the files and folders to the left, double click on the graph.pdf file and am always greeted with a black filled rectangle. I've then attempted to run the following:
- axis("off")
- print -dpdf graph2.pdf
And the graph appears to save to pdf correctly. However, without the axes. Could you please assist me in finding a solution?
P.S. I have already attempted octave --force-gui and graphics_toolkit('gnu_toolkit')/graphics_toolkit('fltk') with no luck.
At the site hosted, the only graphics toolkit available is gnuplot, which support in octave was mostly dropped several versions ago.
gnuplot has the bug you've described. In the link, people got plotting working by rolling back to previous gnuplot versions.
Guess the only way of getting printing working on the site would be signalling about the issue to its administration.
Also, note that octave crudely depicts the copy of the plot in terminal window. That might suffice for correctness check of the plotting code itself.
Alternatively, you can save octave graphics objects with hgsave command, those then can be loaded in octave on another computer to obtain same plot as one that would be drawn there. (Although, at this point there might be no reason for using online interpreter then.)
I'm using the still undocumented HG2-Update to create my MATLAB plots, because they just look that much nicer.
(Source: Yair Altman)
Actually, using the current version Release 2013b it works quite nicely and there are not much issues. Except one wants to export the figures as vector graphics (renderer: '-painters'), especially as pdf.
I use the commands:
saveas(gcf,'test.pdf','pdf')
or
print(gcf,'test.pdf','-dpdf')
There are rendering issues, the print does not contain the whole figure and some parts are cropped or non-default fonts are not recognized.
But I'd really like to stay with HG2 and I'd still like to use vector graphics. Is there any solution or workaround?
Exporting vector graphics using the yet not official HG2-Update is quite an issue. The .pdf-export is still totally screwed up.
What is working fine is the .svg-export, apart from that the boundary box is not set properly.
The long workaround would be:
Save the plot with '-dsvg' (print-command) or 'svg' (saveas-command) as vector graphic, open the file in the open source application Inkscape and save again as .pdf with the Export area is drawing checkmark set.
Quite complicated, so I found a way to do it via command-line directly from Matlab (Inkscape still required!):
filename = 'test';
inkscapepath = '"C:\Program Files (x86)\Inkscape\inkscape.exe"';
%// save as .svg
saveas(gcf,filename,'svg')
%// open and save with "export-area-drawing" set via command line
system( [inkscapepath ' ' filename ...
'.svg --export-area-drawing --export-pdf=' filename '.pdf'])
It takes some time, but works without any known issues for now.
Additionally delete the svg-File afterwards:
delete([filename '.svg'])
I had the same problem and used the workaround from thewaywewalk. Now I discovered the MATLAB function "hgexport" works under HG2 (in R2014a).
An issue still was the paper size. I want to use the same size for all graphs with as little white frame as possible. Here you have to set two sizes:
The papersize is set with set(gcf,'PaperSize',[width height]) and the size of your chart is set through export styles. These are set in "Export Setup" or command line:
exp_style=hgexport('readstyle','default');
exp_style.Width = 'width';
exp_style.Height = 'height';
exp_style.Renderer = 'painters';
Now you can export your pdf:
hgexport(gcf,'pdfname',exp_style,'Format','pdf');
PS: In HG2 you may also use Latex for tick labels:
set(gca,'TickLabelInterpreter','latex');
I have 42 variables and I have calculated the correlation matrix for them in Matlab. Now I would like to visualize it with a schemaball. Does anyone have any suggestions / experiences how this could be done in Matlab? The following pictures will explain my point better:
In the pictures each parabola between variables would mean the strength of correlation between them. The thicker the line is, the more correlation. I prefer the style of picture 1 more than the style in picture 2 where I have used different colors to highlight the strength of correlation.
Kinda finished I guess.. code can be found here at github.
Documentation is included in the file.
The yellow/magenta color (for positive/negative correlation) is configurable, as well as the fontsize of the labels and the angles at which the labels are plotted, so you can get fancy if you want and not distribute them evenly along the perimeter/group some/...
If you want to actually print these graphs or use them outside matlab, I suggest using vector formats (eg eps). It's also annoying that the text resizes when you zoom in/out, but I don't know of any way to fix that without hacking the zoom function :/
schemaball % demo
schemaball(arrayfun(#num2str,1:10,'uni',false), rand(10).^8,11,[0.1587 0.8750],[0.8333 1],2*pi*sin(linspace(0,pi/2-pi/20,10)))
schemaball(arrayfun(#num2str,1:50,'uni',false), rand(50).^50,9)
I finished and submitted my version to the FEX: schemaball and will update the link asap.
There are a some differences with Gunther Struyf's contribution:
You can return the handles to the graphic object for full manual customization
Labels are oriented to allow maximum left-to-rigth readability
The figure stretches to fit labels in, leaving the axes unchanged
Syntax requires only correlations matrix (but allows optional inputs)
Optimized for performance.
Follow examples of demo, custom labels and creative customization.
Note: the first figure was exported with saveas(), all others with export_fig.
schemaball
x = rand(10).^3;
x(:,3) = 1.3*mean(x,2);
schemaball(x, {'Hi','how','is','your','day?', 'Do','you','like','schemaballs?','NO!!'})
h = schemaball;
set(h.l(~isnan(h.l)), 'LineWidth',1.2)
set(h.s, 'MarkerEdgeColor','red','LineWidth',2,'SizeData',100)
set(h.t, 'EdgeColor','white','LineWidth',1)
The default colormap:
To improve on screen rendering you can launch MATLAB with the experimental -hgVersion 2 switch which produces anti/aliased graphics by default now (source: HG2 update | Undocumented Matlab). However, if you try to save the figure, the file will have the usual old anti-aliased rendering, so here's a printscreen image of Gunther's schemaball:
Important update:
You can do this in Matlab now with the FileExchange submission:
http://www.mathworks.com/matlabcentral/fileexchange/48576-circulargraph
There is an exmample by Matlab in here:
http://uk.mathworks.com/examples/matlab/3859-circular-graph-examples
Which gives this kind of beautiful plots:
Coincidentally, Cleve Moler (MathWorks Chief Mathematician) showed an example of just this sort of plot on his most recent blog post (not nearly as beautiful as the ones in your example, and the connecting lines are straight rather than parabolic, but it looks functional). Unfortunately he didn't include the code directly, but if you leave him a comment on the post he's usually very willing to share things.
What might be even nicer for you is that he also applies (and this time includes) code to permute the rows/columns of the array in order to maximize the spatial proximity of highly connected nodes, rather than randomly ordering them around the circumference. You end up with a 'crescent'-shaped envelope of connecting lines, with the thick bit of the crescent representing the most highly connected nodes.
Unfortunately however, I suspect that if you need to enhance his code to get the very narrow, high-resolution lines in your example plots, then MATLAB's currently non-anti-aliased graphics aren't quite up to it yet.
I've recently been experimenting with MATLAB data and the D3 visualization library for similar graphs - there are several related types of circular visualizations you may be interested in and many of them are interactive. Another helpful, well-baked, and freely available option is Circos which is probably responsible for most of the prettier versions of these graphs you've seen in popular press.
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
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
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.
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.
Run Xvfb :1 &, which creates a (virtual) framebuffer X server.
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.
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.
Profit.