May 20, 2012

high quality plots in octave

When you're about to publish in a scientific journal, one problem appears: how do I create high quality plots for my paper?


You can use all kinds of expensive programs (Origin, for example), but free software is as well capable of doing this. For print, you definitely want to use some vector based image formats, of which EPS (encapsulated postscript) is the most common.

Well let's look at a simple eps, created with octave:

generic EPS plot. we have to work on this.
 code for this example is below
This looks quite poor:

  • the proportions of data points, axis, ticks are not good
  • the fonts look messy
  • there is no color
The good news is: we definitely can improve this. The bad news: i tried the example on different machines and depending on the octave version and the installed postscript drivers / conversion tools, the results differ. So, as always the parola is: play with the given values :)

A good idea is to look whether the journal you're intending to publish in has any style guidelines. Often, detailed information about the size, font, and axis labels can be found there.

A list of task that can be done to improve the above plot:

  • we'll use colors
  • we'll use another font: a sans-serif is standard in scientific plots (e.g. Helvetica or Arial). The font size will be changed.
  • we'll change the proportions of the image. The data points and lines are the most important issue on our plot, so we'll make them quite big and fat
  • the outer proportions of the image are changed. In a two-column layout which is common in many publications, often a width-to-height ratio of 2:1 is demanded
  • we'll  make the axis a little thicker. In some cases, it is desirable to have the ticks outside
  • Often, the axis are heavily overloaded, there is too much information distracting from the plot content. This can be reduced by leaving some ticklabels out.
The result looks more nicely:

an improved version.


I hope this is a good starting point. The above pictures where created on an Ubuntu 10.04 machine with octave 3.6.x. Now the code:


clear all;
more off;
%
% create some data: polynoms with random noise
%
points = 15
x = linspace(-5,5,points);
y1 = 0.3*x.^2 + 5 *(rand(1,points)-.5)+15;
y2 = 0.1*x.^3 + 5 *(rand(1,points)-.5);
%
% fit some curves to the noisy data
%
[p1,s1] = polyfit(x,y1,3);
[p2,s2] = polyfit(x,y2,3);
tx = linspace(min(x),max(x),500)
%
% create a generic plot
%
figure(1)
plot(  x,y1,'x',
  x,y2,'o',
  tx,polyval(p1,tx),
  tx,polyval(p2,tx))
xlabel 'X'
ylabel 'Y'
legend('y1',
'y2',
'fit1',
'fit2')
print('generic.eps')


%
% create a more advanced version of the plot
figure(2)
%
% in the plot command
% - define markersize
% - define linewidth
% - assign colors
%
plot(  x,y1,'x'
,'linewidth',6
,'color',[1,0,0]
,'markersize',6
  ,x,y2,'o'
  ,'color',[0,0,1]
  ,'markerfacecolor',[0,0,1]
  ,'markersize',6,
  tx,polyval(p1,tx),
  'linewidth',3,
  'color',[1,0,0],
  tx,polyval(p2,tx),
  'linewidth',3,
  'color',[0,0,1])
%
% now let's adjust the axis:
% - make the line thicker
% - make the ticks outside
% - adjust ticklength
% - use custom ticks
% - apply custom ticklabels
%
set(gca(),
'linewidth',2,
'tickdir','out',
'ticklength',[0.005,0.005],
'xtick',[-6:6],
'xticklabel',{'','-5','','','','','0','','','','','5',''},
'ytick',[-20:10:30],
'ylim',[-20,30],
'yticklabel',{'','-20','','0','','20',''})   
xlabel 'X'
ylabel 'Y'
%
% the legend shall appera on the bottom right of the plot
%
legend('y1','y2','fit1','fit2','location','southeast')

% let's print this thing to a eps.
% we use a custom size of 900x450,
% a defined Font and Size
% and the depsc2 driver (EPS 2 color) driver
print('test2.eps','-S900,450',
'-depsc2',
'-F:Helvetica:12',
'-tight'
)


I guess this is a good starting point for creating printable plots that look good. When you're not sure what can be done: Have a look at the attributes of your graphic and axis objects:

get( gcf())   %get current figure
get( gca())  %get current axis

you can set it with the set command

set( gca(), 'property','value')

Have a look at the octave manual. The mathworks website can also be useful, sometimes ;-)

11 comments:

  1. Hi.
    Very nice.
    But I have a problem: I make my lines thicker and its OK on the screen but the saved eps has the lines at the original width (that is, are thin). Any suggestion?

    ReplyDelete
  2. Hi "Anonymous",
    thanks for the feedback.
    Well, the code works fine on my machine (ubuntu 10.04, octave 3.4.3), the result produces nice fat plot lines (see http://tmblr.co/Z11XJuStA9Vk for picture).

    i could imagine the following problems:

    - missing font: maybe Helvetica isn't installed on your system. try to leave the "-F:Helvetica:12" tag out of the print command.
    - wrong or missing Postscript drivers. This is more or less a common problem. Using your package manager (on linux) and (re-) installing ghostscript, pstoedit and imagemagick and maybe also the corresponding dev-files can help to make your machine fit t oproduce proper EPS files
    - gnuplot issues: check and maybe reinstall gnuplot (if you're using it)
    - old versions: build the latest octave / gnuplot binaries ...

    ReplyDelete
  3. one more comment (i've also tested octave-3.6.2)

    ReplyDelete
  4. thank you! it was very useful to me :D

    ReplyDelete
  5. any thoughts on preparing these plots for a grayscale eps? octave seems not to produce the linestyles ':' '--' or '-.' as nicely as others... (3.6.1)

    ReplyDelete
    Replies
    1. Maybe one ugly way could be to post-process the picture in inkscape (free software):

      Export the picture as EPS, with all lines as *solid* and *black*
      Import it into inkscape (make sure to have pstoedit installed), click into the group. Then you can select the lines and adjust the line style.

      I know this is not a very nice style and problem will rise if you have noisy data but maybe it helps.

      Delete
  6. Pretty nice. Thanks.
    My biggest issue with Octave plots is the types of data point markers available - asterisks, open circles, plus signs --- not necessarily the most recognizable set of possibilities.
    Any ideas about that?

    ReplyDelete
    Replies
    1. you have also the option to plot the following symbols additional to asterisks ("*", open circles, "o", plus signs, "+" , dots "." and crosses "x":

      plot(x,y, "s") SQUARES
      plot(x,y, "d") DIAMOND
      plot(x,y, "v") TRIANGLES

      these all are open symbols. you can created filled symbols using the
      "markerfacecolor" tag by setting it to the same color as the "color" tag ist, e.g:

      plot(x,y, "o", "color", [0,0,1], "markerfacecolor",[0,0,1])

      (tested in 3.6.3)

      Delete
  7. Hi,
    I am having problems with the legends over lapping on each other the names for instant even though i have set them to be horizontal and outside the graph - but i have the fonts set to be 18 in Helvetica
    - any tips on how to get it right
    - and the marker face colour is there any default option to have the same markerfacelor as the colour as the shapes..? or do i have say it every time like 'ks', 'markerfacecolor', 'k' ??

    Kind Regards,
    Hasan

    ReplyDelete
    Replies
    1. To be honest, I have no real clue how to help you about with your legend problem. A possible way is to vary the different sizes to see what the result will look like.
      If you want a more controllable but also open source solution for scientific plotting, i recommend you the package matplotlib for python. i personally am using it since a year or so instead of octave.

      Delete