While working on a concept and draft for my bachelor thesis I decided I wanted charts. Bar charts, line charts, multiple line charts, you get the point.
Now, if you tried to include images in a LaTeX document you probably know already that resolution matters. A lot. You want your printed document to look nice and professional so you can be proud of it, but its charts are all blurry and pixelated. Even worse, you rendered your charts with a random tool of your choice and they look great but the fonts don’t match the target document’s, they don’t scale (because they are part of the image).
Well, at least those were my problems. Then I discovered output modes of Octave. In tex output mode it generates two files: an encapsulated postscript (.eps) and a LaTeX document. Just include (\import or whatever you want to use) the latter in your main document and marvel at the astonishing results!
Here’s my Octave function generating three graphs in one plot. You can call it like that:
threegraph([0 1 2; 2 3 4; 5 5 7; 8 1 0;], {'One', '', 'Three', ''}, 'testplot', 'Some random values', {'Graph one', 'Graph two', 'Graph three'});
function[] = threegraph(values, xticklabels, plotname, labely, legends) ## UPPERBOUNDS = 0.4; ## printf("Printing %s; %d values, %d labels\n", plotname, length(values), length(xticklabels)); % Generates ticks ignoring empty labels. xtick = (1 : length(values)); for i = 1 : length(xticklabels) if (strcmp(xticklabels(i), '') != 0) xticks(i) = 0; endif end % first graph handle = plot(values(:,2), '0'); set(handle(1), 'linewidth', 2); hold on; % second graph handle = plot(values(:,3), '1'); set(handle(1), 'linewidth', 2); % third graph handle = plot(values(:,4), '2'); set(handle(1), 'linewidth', 2); handle = plot(values(1:end-1,:), '0o', 'markersize', 5); axs = axis(); % correctly clip x-axis axs(2) = length(values) + 1; % set upper bounds mval = max(max(values)); axs(4) = mval + mval * UPPERBOUNDS; axis(axs); legend(legends); ylabel(labely); set(gca, 'xtick', xtick); % set labels set(gca, 'xticklabel', xticklabels); % now make a nice tex document ready for \include print(strcat(plotname, '.tex'), '-dtex', '-S850,350'); hold off; endfunction
The next one was a bit trickier, I wanted a bar graph and the labels to be rotated. Fortunately I found a mailing list entry by Eric Chassande-Mottin who provided his solution for rotating labels.
function[] = bargraph(values, xticklabels, plotname, labely) ## UPPERBOUNDS = 0.02; ## printf("Printing %s; %d values, %d labels\n", plotname, length(values), length(xticklabels)); % Moving labels' position results in really weird plots, so we just append % trailing (LaTeX) spaces here as a workaround. for i = 1 : length(xticklabels) xticklabels(i) = cstrcat(char(xticklabels(i)), "~~"); end handle = bar(values); ylabel(labely); axs = axis(); % correctly clip x-axis axs(2) = length(values) + 1; % set upper bounds axs(4) = max(values) + max(values) * UPPERBOUNDS; axis(axs); % define which bars to label xtick = (1 : length(values)); set(gca, 'xtick', xtick); % set labels for bars set(gca, 'xticklabel', xticklabels); % get position of current xtick labels xlabelpos = get(gca, 'xlabel'); xlabelstring = get(xlabelpos, 'string'); xlabelposition = get(xlabelpos, 'position'); % construct position of new xtick labels yposition = xlabelposition(2); yposition = repmat(yposition, length(xtick), 1); % disable current xtick labels set(gca, 'xtick', []); % set up new xtick labels and rotate 45 degrees newticks = text(xtick, yposition, xticklabels); set(newticks, 'rotation', 45, 'horizontalalignment', 'right'); % now make a nice tex document ready for \include print(strcat(plotname, '.tex'), '-dtex', '-S850,350'); endfunction
Run the above function to get an idea of the possibilities that Octave offers. I’m really no expert in the Octave language (neither MATLAB by the way), but the results are so great I thought I had to share this.