USGS logo - Archived Page (no longer updated)

Customizing Matlab Axes

Dr. Charles R. Denham, U.S. Geological Survey, Woods Hole, MA 02543
Send suggestions and comments to cdenham@usgs.gov


Motivation

In oceanography and many other sciences, there are two especially important tickmark requirements: dates and longitude/latitude geographic positions. Each one is complicated by its non-decadal numbering scheme: for the "year-month-day-hour-minute-second" system, the bases are (approximately) [1 12 30.44 24 60 60], while for the hexagesimal "degree-minute-second" units, they are [1 60 60]. And other non-linear scales abound, such as with probability-paper in statistics.

In Matlab graphs, tickmarks are distributed according to just two selectable scales: "linear" or "log". Any other kind of labeling is expected to be engineered by the user. This is a formidable task that requires some understanding of Matlab graphics..

Matlab adjusts the number of axis tick-marks to be pleasing, in keeping with the curent size of the graph and its chosen font. Since the resizing of a figure window may demand different tickmarks, it makes sense to automate the updating of tickmarks, rather than hardwiring them into place.

This kind of challenge occurs during printing, for example, when Matlab temporarily resizes the graph to fit the targetted paper, and then reverts to the original size. If a user-supplied "ResizeFcn" is active, it will be called twice for this purpose.

The customization of tickmarks requires that we go behind the scenes to cajol Matlab into doing the required work automatically.

Invisible Axes

Rather than struggling to outdo Matlab by computing our own tick-marks, we can get Matlab to do the work for us, by using a temporary invisible "axes" object, which has the same size ("Position" and font ("FontStyle" and other font properties.) as the original.

original = gca
position = get(original, 'Position')
fontstyle = get(original, 'FontStyle')
temporary = axes('Position', position, 'FontStyle', fontstyle, 'Visible', 'off')

We then transform the original axis limits into the desired units and use the tick positions and labels that Matlab itself selects for the temporary axis. The final step is to map (inverse-transform) the ticks back to the original axis.

xlim = get(original, 'XLim')
set(temporary, 'XLim', TRANSFORM(xlim))
xtick = get(temporary, 'XTick')
xticklabels = get(temporary, 'XTickLabels')
set(original, 'XTick', UNTRANSFORM(xtick), 'XTickLabel', xticklabels)

Degrees

Finally, some attention needs to be given to the labels themselves. Matlab does not know how to compute a "nice" sequence of "degree-minute-second" positions. The user, on the other hand can easily reformat "decimal degrees" into "degree-minute-second" units. Since the existing decimal-degree labels are already "nice", the "deg-min-sec" will likewise be nice, since the number 60 is so composite.

Dates

For dates, the situation is more complicated, because we are accustomed to seeing the first-day of the month labeled, or perhaps days [1 8 15 22], or perhaps each Sunday. Proceed as follows. Scale the temporary axis using a convenient base unit, such as decimal years if several years are spanned, or decimal months if it happens to be months, etc. Because months have irregular lengths, use an average month (365.25/12 days) to get the approximate tick locations, then nudge them forwards or backwards until each one falls exactly at the beginning of a convenient day, say the first or fifteenth of the month. Since the overall range of dates is known, one can experiment with limits expressed in years, months, days, etc., until the resolution of the result is adequate. Once done, the "datestr" function can be used to format the labels themselves. (Note that date-strings are long, so half of the tick-labels should be blanked to avoid crowding.)

Resizing Figures

To force the automatic updating of a Matlab figure window, set its "ResizeFcn" to an executable string. Then, if the "Resize" property is "on" (the default), the window will be updated whenever it is resized.

Program

Here is ezaxis.m, a simple demonstration of mapping axis tickmarks. Execute "ezaxis" at the Matlab prompt to see a demonstration.