Wednesday, January 18, 2012

Animated GIF for Presentations

If you're using powerpoint for presentations you know how tricky animations can be if you're presenting on different computers. PPT 2010 seems to be better at handling the problem of embedding files but I don't know. PDF can now play video but it'll probably be awhile before the world as a whole can use it. That means LaTeX and beamer might not be useful yet (I LOVE beamer presentations though!).

I've mentioned before that I work in an office with both Mac and PC and a variety of PPT versions so I need compatibility across. I also want decent resolution without massive files attached to my presentations so I'm converting my .avi to animated .gif. These files seem to be about 1/10 to 1/5 the file size and SHOULD embed easily into a powerpoint document.

I'm not going to write out the steps to making nice animated .gif files because this guy (xFL1PPYx) did such a WONDERFUL job of showing how to do it. He uses GIMP and GAP (GIMP Animation Package). Both are free. The links are given in his video description.

Check it out!

Friday, January 13, 2012

Generating Publication Quality Figures in Matlab


Updated* See Step 7 - Post Processing

Matlab is wonderful for visualizing solutions quickly for the purposes of debugging or exploring numerical solutions. It is pretty bad at figure formatting though. In fact, I don't feel comfortable putting Matlab figures directly into documents because they look so unprofessional. Matlab does have the workspace toolbox thing, but that's not the best. Mostly because the export is exactly the same size as the figure on the screen and setting that size is really inconvenient so axis of adjacent figures don't usually line up well.

This is how I do it:
First we are assuming either the correct sizing for a figure that will fit on half a page so that 2 can be side by side on a 6.25 (or 6.5) inch text width OR that I have one elongated figure that fills the whole width - like a contour plot.

1) Specify the dimensions

% For Normal Figures
height=1.0/1.618; % width/golden ratio
width=1;

% For Wide Figures
% height=1.0/1.618; % width/golden ratio
% width=2;

scale=300; % 3.13 inches

I choose the golden ratio because it's considered aesthetically pleasing to the eye. It works well for large figures, but it might not be perfect for small figures. Just remember if you want to scale from a known dimension in inches use a converter to convert to pixels. 300 pixels is 3.13 inches

You can also position the figure on the screen
xpos=50;
ypos=500;

2) Define the function to be plotted. For the example, I generate one on the spot but this could be an import function
x=0:.01:2*pi;
f1=cos(x);
f2=sin(x);

3) Generate the figure. This doesn't just mean plot the data. The figure is comprised of the figure dimensions, the plot area, the bounding box, etc.. We also want to set the fonts and position

figure; % Create Figure
axes('FontName','Times New Roman') % Set axis font style
box('on'); % Define box around whole figure
set(gcf,'Position',[xpos ypos scale*width scale*height]) % Set figure format

4) Plot the data

hold on
plot1=plot(x,f1,'Color',[1 0 0]);
plot2=plot(x,f2,'Color',[0 0 1]);

by plotting each function as a different plot command and defining plot1 and plot2, we have unique control over the format of each data set.

5) Set Plot properties. This is different than setting figure properties and refers to the data set format

set(plot1,'LineWidth',1,'LineStyle','-');
set(plot2,'LineWidth',1,'LineStyle','--');

% Set Axis Limits
xlim([min(x), max(x)])
ylim([min(f1), max(f1)])

% Create xlabel
xlabel('\xi','FontSize',11,'FontName','Times New Roman','FontAngle','italic');

% Create ylabel
ylabel('\eta','FontSize',11,'FontName','Times New Roman','FontAngle','italic','rot',0);

% Create Legend
hleg1 = legend('$\cos(x)$','$\sin(x)$');

% Set Legend Properties
set(hleg1,'Interpreter','latex')
set(hleg1,'Location','SouthWest')
set(hleg1,'box','on')

There are more properties that can be set, but i just took the ones I use most.

6) Export figure
fig = gcf;
style = hgexport('factorystyle');
style.Bounds = 'loose';
hgexport(fig,'Example_Figure.eps',style,'applystyle', true);
drawnow;

print -depsc2 -tiff myfile.eps

There is something weird here: i don't think i have to use both the hgexport (like clicking File-Save As) and print but I don't get the right format without using both.

7) Post processing. This is really unfortunate. The problem is that Matlab doesn't embed fonts in eps files correctly (or at all). There are functions such as export_fig and exportfig that claim to do this, but I've not had any luck. Part of it is that I don't have time to mess with all the settings and syntax that comes with using other packages. Part of it is my frustration with the whole nonsense.

An option many people seem to use is Adobe Illustrator. The process goes: Open the eps and convert the text to outlines. I think this replaces the text with lines and fills so that the letters appear, but aren't actually text anymore. That's a good idea, but I spent some time poking around the trial and couldn't figure out how to set the damn page dimensions so the exported eps was back to its original size. It would always export it with a big white space around it. I think there's something about the clipping box but I don't have time to mess with this garbage. I'm a scientist, not a graphic designer.

Next option: ACD Canvas. Open the eps in canvas and convert to canvas object. Magically (expected), it imports the eps figure with the correct dimensions! Then select all and "convert to path." I'm not completely sure what goes on behind the scenes with this operation, but it appears to take whatever is selected and lump it all into some kind of vector graphic. Again, the text is no longer dependent on a font. The problem with this is that there is no more editing so make sure it's what you want before you convert it. This works fine and produces nice figures.

UPDATE - Canvas costs money beyond the trial version. Boo. Inkscape is the solution! It's a free, open source program that will do this stuff MUCH easier than Adobe and even easier as Canvas. Open the eps file. Make sure the fonts imported correctly. If not, fix them! Then save as eps. The dialog box will offer some really cool stuff for latex but we don't need that right now. Make sure the box "Convert texts to paths" is selected and the "export area is drawing" is selected (I don't know about the "export area is page" that sounds counter to the previous box but I left mine checked). I don't know what the rest does so leave it or not. It doesn't seem to matter. The important part is that the text is converted to paths!

Beyond that, Inkscape (and the others) let you edit figures. For instance, Matlab will automatically adjust the position of the axis and labels depending on the number of digits in the label. That means the axis won't necessarily line up correctly in the document. Inkscape can adjust the axis dimensions and the location of the labels and titles so that they all look correctly! Awesome!

This isn't perfect but it works pretty well. If you're without a better option, then this is definitely a viable possibility. Here is the whole matlab code:

%% Figure Generator with Format
% =========================================================================
clear;clc;close all

% =========================================================================
% Specify Dimensions and Position on Screen
% =========================================================================
% -------------------------------------------------------------------------
% Figure Dimensions
% -------------------------------------------------------------------------

% For Normal Figures
height=1.0/1.618; % width/golden ratio
width=1;

% For Wide Figures
% height=1.0/1.618; % width/golden ratio
% width=2;

scale=300; % 3.13 inches
% -------------------------------------------------------------------------
% Figure Position on Screen
% -------------------------------------------------------------------------
xpos=50;
ypos=500;

% =========================================================================
% Define Functions to be Plotted
% =========================================================================
x=0:.01:2*pi;
f1=cos(x);
f2=sin(x);

% =========================================================================
% Generate Figure
% =========================================================================
% -------------------------------------------------------------------------
% Figure Properties
% -------------------------------------------------------------------------
figure; % Create Figure
axes('FontName','Times New Roman') % Set axis font style
box('on'); % Define box around whole figure
set(gcf,'Position',[xpos ypos scale*width scale*height]) % Set figure format

% -------------------------------------------------------------------------
% Plot Data
% -------------------------------------------------------------------------
hold on
plot1=plot(x,f1,'Color',[1 0 0]);
plot2=plot(x,f2,'Color',[0 0 1]);

% -------------------------------------------------------------------------
% Plot Properties
% -------------------------------------------------------------------------
set(plot1,'LineWidth',1,'LineStyle','-');
set(plot2,'LineWidth',1,'LineStyle','--');

% Set Axis Limits
xlim([min(x), max(x)])
ylim([min(f1), max(f1)])

% Create xlabel
xlabel('\xi','FontSize',11,'FontName','Times New Roman','FontAngle','italic');
% xlabel('$\xi$','FontSize',11,'FontName','Times New Roman','interpreter','LaTex','rot',0);

% Create ylabel
ylabel('\eta','FontSize',11,'FontName','Times New Roman','FontAngle','italic','rot',0);
% ylabel('$\eta$','FontSize',11,'FontName','Times New Roman','interpreter','LaTex','rot',0);

% Create Legend
hleg1 = legend('$\cos(x)$','$\sin(x)$');

% Set Legend Properties
set(hleg1,'Interpreter','latex')
set(hleg1,'Location','SouthWest')
set(hleg1,'box','on')

% =========================================================================
% Export Figure
% =========================================================================
fig = gcf;
style = hgexport('factorystyle');
style.Bounds = 'loose';
hgexport(fig,'Example_Figure.eps',style,'applystyle', true);
drawnow;

print -depsc2 -tiff myfile.eps

Friday, November 11, 2011

Figure placement in Word

Word handles figures pretty poorly for anything substantial. I've complained about it's inadequacies when writing scientific documents often.

Fixing figures to page locations is a bad idea when there are lots of them to put in because adding content above them will likely make any subsequent figures shift and overlap. This is kind of because they are anchored to a paragraph and a page location. Rather, anchoring them to a paragraph and allowing them to float with the text will work much better in the long run.

The best way, is to use frames although the necessity is going away with newer versions of word. Originally, frames ensured that the content within them appeared on the same layer as the content outside where text boxes floated on another layer. This makes cross-referencing impossible because the layers don't play nice. I'm not sure this is the case anymore though. In new versions of word you have to add the "Format Frame" button to the quick bar because it's not available by default.

Now, don't make frames and put figures into them. Do it the other way around. Put the figure into the document. Right click and insert caption. Then highlight the caption and the figure and click the format frame button. It will make a frame the correct height and the width of the page. Position the figure within the frame (i.e. center it) and you're done. The frame will be anchored to the next paragraph and will float nicely!

Removing field codes in Word Documents

Field codes are used to create automatically generated content like cross-referencing, captioning, list of figures etc. Word is complete crap for technical writing and cross-platform collaboration but these things decent and should be used.

Why you would want to remove field codes? Beats the hell out of me. Just kidding. Submitting documents for publication might require fields removed. Cross-platform versions of word sometimes break the fields. Old versions of word do the same thing. Or if you're like me and you work with people who waste time by rewriting all the fields manually because they openly refuse to learn how to do it automatically. Seriously. I wouldn't care if it didn't waste my time but it always does.

Screw that nonsense. I found how to do both. I write up my reports the correct way - with fields - and strip the final version so that none exist and they can piss around doing whatever it is they do.


just like updating the whole document select all

ctrl-A

then strip the fields with

ctrl+shift+F9

Presto Manifesto!
Now that I can avoid intentionally doing things inefficiently, I feel much more motivated to finish this report. Thanks KG from the link!

Of course, there is a cross platform option that will always work...LaTex. Damn Word is crap for my work.

Sunday, July 10, 2011

Unsorted reference numbering when using a list of figures and a citation is in the caption

This is a dumb problem that has a little attention. I figured it out from

If you use the cite command in the a caption AND have a list of figures or list of tables generated, then the unsorted numbering will be wrong. It will start numbering the references from the list of figures and not from the start of the actual document. Therefore, the first reference in the body of the document will not start at 1. To fix, use the optional command syntax for \caption:

\caption[This is the caption]{This is the caption \cite{REF}}

Just repeat the caption in the brackets and omit the \cite command. You'll probably have to rerun Latex twice and maybe bibtex once before the changes are updated but it works! The article I linked to says you might have to use the \protect{\cite{REF}} command, but I didn't find it necessary.

Friday, March 18, 2011

PhotoImpact: Stop Automatically Adjusting Image Size in Properties Menu

Ok. So I tried PhotoImpact from ulead a long time ago. Not bad. They have a free trial and the full version starts at 50 dollars. That's a whole lot better than photoshop! I'm not good at image stuff but It was useful for making simple drawings. There was one problem I ran into and apparently others too.

Problem: When I make an object and size it, if I go back to the properties window the image has been resized by one or two pixels in some direction.

For most things, this isn't that big a deal and you'd never realize it. But if you need tight margins or exact positioning then this is awful! If I center a 50 by 50 image on a page (25 to the left of center and 25 to right) if it is resized to 50 by 51, then I can't center it if my original image has an even number of pixels.

Solution: Turn off anti-aliasing when creating the image. This option is in the tool properties menu. Click on the shape drawing tool. In the far right bottom of the top tool bar there is a button that looks like a window with check boxes and an arrow. This is the properties menu. Then in that menu uncheck anti-aliasing.

I get it, this feature makes lines smooth. But seriously, this is a terrible feature to have selected by default and hidden away with no explanation of what is going on with your figure.

All in all, I like this program. The learning curve is ok. The menus and settings are pretty damn awful but probably no different than photoshop. Best of all, it's cheap and does what it needs to do. If you don't need to get crazy with photoshop - or even if you do, you might want to see if this will work for you first.

Monday, March 14, 2011

Hyperlink Combo Boxes in Excel with VBA



There is a lot of forums about how to do this and the best I've seen is using named ranges and data validation lists. I think there is a better way.

Problem: I want to make a drop down menu with hyperlinks to other worksheets
Solution: Write a simple VBA macro (I promise, it's really easy!)

Step 1: Make sure all your worksheets are cleanly titled. If you have several distinct groups of worksheets, then the first word of the title should be the same for the group. In this example, I have several worksheets grouped in "Tournament" so my titles are like "Tournament Setup", "Tournament Registration" etc.

Step 2: Create a worksheet to house all the menu options. This is not necessary if you can efficiently generate list items from the original worksheets. For example purposes, we will keep all our entries here. Also, if you want the code to work as shown below follow these steps exactly and name this sheet NavMenu.

Step 3: Designate a column for the menu items. If you want the code provided to work without modifying the cell locations, then the sheet should be built like
Cells B11:B17 are the menu items. For now, just type in the menu items in this range. The menu items should NOT include the group label. This will be added automatically in the code. Cell B8 is the group label. You can go ahead and add this too.

Step 4: Create a form control combobox (not activeX). Right click and click format control. In Input Range select the range containing the menu items. Here it is NavMenu!$B$11:$B$18. I include Cell B18 so I have a blank item to rest the menu to. You'll see what i mean below.

In the cell link box enter NavMenu!$D$9. It is important to specify the NavMenu worksheet since you'll use this on many pages and it must only modify the cells in the NavMenu worksheet, not the current sheet. Now you should have a combo box that contains all the menu items and posts the index in cell D9.


Step 5: Cell D10 is the name of the menu item. To do this we use the offset command. In Cell D10 enter =OFFSET(B8,D9+2,0,,) . This takes B8 as the reference cell, counts value(D9)+2 rows down, and displays whatever is in that cell. In our case, it's the menu item name.

Step 6: In Cell D8 enter =COUNTA(B11:B18). This is not shown in the picture above because i just added it. It counts the total number of non blank cells in the range. I include B18 because when I insert new item, the range will automatically adjust. New items are inserted in the menu by insert (shift cells down) at B18.

Step 7: Open up the Developer menu (search google if it's not already displayed in your ribbon) and visual basic. Create a new module for the menu and paste:

Sub TournamentMenu()
Dim PageName As String, GroupName As String, SheetName As String
Dim ItemNum As Integer
ItemNum = ['NavMenu'!D8] 'number of menu items
PageName = ['NavMenu'!D10] 'page name
GroupName = ['NavMenu'!B8] 'group name
If PageName = "0" Then 'condition to exit if blank
Exit Sub
End If
SheetName = GroupName & " " & PageName 'join the groupname and pagename
Sheets(SheetName).Select 'navigate to the sheet
['NavMenu'!D9] = ItemNum + 1 'reset the menu to the blank entry
End Sub

Step 8: Right click on the combobox and click assign macro. Select TournamentMenu and you're done!

Repeat for different menus. Modify the cell locations for ItemNum PageName and GroupName for each menu.