File Exchange

image thumbnail

oaxes - central axis lines through an origin

version 1.8 (42.1 KB) by

Draw central axis lines through an origin point.



View License

Oaxes creates a set of axis lines through a specified origin point. Oaxes supports both 2D and 3D views, ticks and tick labels, axis labels, log-scaled axes, and has a plethora of properties, analogous to normal axes properties, that give control over the oaxes object's appearance. In addition, various oaxes-specific properties give the user control over features such as arrows at the axis ends and the extent of the axis lines.

By default, the origin is set at the center of the axes limits, and will remain centered if the parent axes limits change. If a fixed origin point is specified, the axis lines will be drawn using that point as the origin. Additionally, the oaxes object will automatically update in response to changes to many of the parent axes' properties.

See the help text in oaxes.m for more information, including examples.

Oaxes uses a number of undocumented MATLAB features which may cause problems in older versions of MATLAB. If there are workarounds that do not require significant changes, I will add them to the code. MATLAB version 7.10.0 (R2010a) was used to develop and test Oaxes.

Installation: Unpack the contents of the .zip file, then add the top-level folder ("customplots") to the MATLAB path.

Comments and Ratings (31)

John Barber

John Barber (view profile)

The graphics engine in MATLAB underwent a major revision in R2014b. Unfortunately, the current version of oaxes is not compatible with it. I hope at some point to rewrite it in a compatible way, but for now there is no way to use it on R2014b.

Ameya Sathe

Perhaps I am missing something obvious, but I am not able to get your package working even with a simple example of a 2D plot that you have provided in the oaxes.m file. I am using Matlab R2014b on a Windows 7 machine, and added the customplots folder using either the Set Path tab in the Home tab, or using addpath(genpath('MyPathOfCustomPlotsFolder')). I get the following error:

Undefined function 'customplots.oaxes' for input arguments of type ''.

Error in oaxes (line 656)
OA = customplots.oaxes(hAx,pvPairs);

Please help!

John Barber

John Barber (view profile)

Thanks for the clarification. Yes, that would be an interesting use case. When I get the chance, I'll take a look at how much effort that would take to implement within the existing code.



what I mean is to create the axis at arbitrary rotation compared to matlab x,y,z directions. For instance, if campos(camtarget + 50/sqrt(3)*[1,1,1]); and then create an oaxis that has for instance x' pointing toward the camera, y' toward the right of the screen and z' is up on the screen. I'm not saying it has to be define compared to the camera position, but some way to rotate it compared to original x,y,z. I agree, in general once it's define, it should remain fixed, such that it corresponds to an actual coordinate system.

Paul de Haas

John Barber

John Barber (view profile)

1) See my answer and suggested workaround to Felix's question about multiple OAXES. It is not currently possible to have more than one OAXES exist in a given axes. I will consider it for a future release.

2) There is not a way to specify an offset. If you want to show a translated coordinate system, you could simply set the tick labels of the OAXES object to custom values representing the translated coordinates. Be sure to set the tick labels and not the ticks themselves. This trick also works on the standard MATLAB axes object - the tick labels can be independent of the values of the ticks. The drawback is that if the tick locations change (due to limit changes, etc.), the manual tick labels will be incorrect. I'll consider adding an 'offset' property in a future release.

John Barber

John Barber (view profile)

Like many of the low-level MATLAB graphics functions, OAXES does not redraw until the MATLAB event queue is processed, which doesn't necessarily happen when you would like it to during function execution. Instead of using the PAUSE command, you can call the MATLAB function DRAWNOW() (see the help file for DRAWNOW for more information). Alternately, you can force the OAXES object to redraw by calling its DRAW() method. If you have a handle OA to the OAXES, simply call OA.draw(). If you don't have the handle, calling oaxes('draw') should also work as long as it can find the OAXES object.

I'm not sure what you mean by "rotate the axis". In 3D views, the axis lines rotate along with all other drawing objects as the camera location is moved. Trying to keep the displayed axis lines fixed on camera moves means that the lines would no longer correspond to the coordinate system. Although it would be interesting to create a camera-independent display mode for a given object (e.g. apply a transform to the object that undoes the effects of the camera location change), that is not in line with the motivation for writing OAXES.

John Barber

John Barber (view profile)

(1) I'm not sure what you mean by inside vs. outside the axis. If you are referring to which side of the axis line the labels are drawn on, then there is currently no way to specify this, but I'll consider adding one in the next release. If you are referring to inside and outside of the plot box/cube, OAXES always draws the labels next to the axis lines, which are always inside of the box.

(2) No, it is not currently possible to define minor ticks. They are calculated automatically for log-scale axes, and not shown for linear scaling. This capability might be added in a future release.

(3) It is not possible for more than one OAXES to exist inside of a given axes. If you want to show more than one OAXES on a given plot, you could try overlaying additional axes objects with transparent backgrounds, and limits linked to the original axes, each containing an OAXES object. See the MATLAB functions linkaxes() and linkprop() for more information.


Also, a suggestion; it would be nice to be able to rotate the axis. Maybe even have an option to keep it aligned with the current camera direction.


This is really great. One weird thing, if I use this in a script and I try to set h(X|Y|Z)Label, it does not work correctly. But if I insert a pause(1) immediately before, it does work.

Hi, I have a problem. I'm making a GUI to show easy roto-translation. Therefore I have to print more reference system on the same plot.
1) oaxes seems to ignore the hold on command. I cannot plot 2 coordinate system on the same plot.
2) can I reset the origin? I mean image I have a point with coordinates (1,2,3) if I translate a reference system form (0,0,0) to i.e. the point (2,2,2)the new coordinates for the point with respect to the new reference system centered in (2,2,2) are (-1,0,1). thus if I give the command oaxes([2 2 2]) what I get is a new reference sys in the point (2,2,2)but the scale reading is wrong(1,2,3) r better is correct wrt the previous ref system.
Is it possible to give an offset to the scale in order to fix it?
I wish to shoe you an image...


Felix (view profile)

I am missing a few functions or can't find them:
-How can I make the ticklabels appear on the outisde of the axis instead inside?
-Is it possible to define the minor ticks separately?
-Is it possible to set multiple axis limits (to make it appear like multiple small axis instead of one long axisLine)

John Barber

John Barber (view profile)

@Mikael: Thank you for the kind feedback. You can try Christian's modification to not display negative arrows. See his comment from 05 Jan 2013 for a link. (Disclaimer: I have not tested this code). I'll think about adding this functionality in my next update, but I'll have to put some thought into the best way to implement it.

Adding grid lines has been on my todo list for a while. Hopefully I'll have some time in the next month or two to work on it. Right now, if you want grid lines, you have to un-hide the parent axes (oa.HideParentAxes = 'off') and turn the grid on as usual. Unfortunately, you end up with the parent axes' axis lines, ticks and tick labels as well - it gets kind of cluttered.

@Christian: Thanks for the kind feedback. I'll take a look at your modified code and consider adding it as an option in my next update.

@cpas1940: If you want to change the label rotation, you can access the handles of the labels in oa.hXLabel, oa.hYLabel, etc. Then you can set the 'Rotation' property as well as any other text properties directly. I'm not sure what you mean by 'having the ylabel centered at (0,0)'. If one of the ylabels were located at (0,0) it would no longer be a label on the end of the axis (assuming oaxes is centered at (0,0) and the limits are [-a +b]). If you are talking about having a rotated label be centered around the y axis line, you can play with the 'HorizontalAlignment' and 'VerticalAlignment' text properties of the labels. Here is an example:

oa = oaxes;
% (The negative-axis label is now rotated by 90 degrees, but not centered correctly)
% (Now it is centered and no longer overlapping the end of the axis line)



Another it possible to rotate y-axis label 90-degree and have it centered at (0,0)?

Second question: Is it possible to get grid working?

Excellent job! Question, though: I would like to get rid of the negative arrows. How can I do that? There doesn't seem to be any property that can be set to achieve that. I am not fluent enough in Matlab to identify where in the code they are actually generated.


John Barber

John Barber (view profile)


The 'HideParentAxes' property controls the visibility of the box around the figure. The default value of 'on' will hide the box, ticks/ticklabels and other features of the parent axes object. You can set this property to 'off', either in the call to generate the oaxes object, or on an existing oaxes object using a function call, set(), or dot notation:
OA.HideParentAxes = 'off';

As you already discovered, the labels for each axis come in pairs (unlike a normal MATLAB axes). The labels should be specified as a <2x1 cell> containing the negative and positive labels, and simply setting the negative label to the empty string will hide it. For example:
OA.XLabel = {'';'+X'};


Nevermind...I figured that out. Now is there a way to keep the box around the outside of the figure?

This is great! I am wondering if there is a way to remove the axes labels and use the xlabel and ylabel in the property editor. Specfically, I do not want the "negative" axis labels. The code is

function z=graph(x)


Great file!It really did the job for me!
Gongats to the creator John Barber!


Oaxis worked very well for me - thanks for sharing, John.

I just wanted 2 arrow heads though (one to the top and one to the right), and modified the customplots/@customplots/@oaxes/methods.m as follows:

It would be nice to have a documented option instead of my hack.

John Barber

John Barber (view profile)


Thanks for the feedback. I could not reproduce your problem exactly, but here is some information that might be helpful:

Your example code is setting the 'XTickLabel', 'FontName', etc. properties of the parent MATLAB axes (the handle returned by gca), not the properties of the oaxes object. (However, your code does directly set the oaxes object's 'XLabel', 'XColor', etc. properties, and you do not indicate any problem with this part of your code). As documented in the oaxes help, upon initialization, the various text properties of the parent axes are copied to the oaxes, but are then independent. Your code will have no effect on the oaxes tick label font properties. To set the oaxes object's tick label font properties, use the following syntax:

set(oa,'TickLabelFontName','Times New Roman','TickLabelFontSize',14,...)

Note that the pertinent property names for the oaxes object all start with 'TickLabel', unlike the MATLAB axes object. See the oaxes help for a complete list of property names. (I'm not sure why I named them that way - if it bugs enough people, I'll change the names to correspond to the MATLAB axes properties). For both oaxes and MATLAB axes objects, you cannot set different text properties for the x and y axis tick labels - the properties affect each axis.

There is a bug in oaxes that in some cases (including the default case) results in the tick labels not being redrawn when the tick label text properties are changed. I will release an update shortly to fix this. For now, the workaround is to force a redraw after changing the tick label text properties using any of the following (where oa is the handle of the oaxes object):

oaxes draw

Your code sets the 'XTickLabel' property of the parent axes, but not the 'XTick' property. I strongly recommend not doing this because it can lead to incorrect tick labels. For example, type xlim([-1 5]) after setting the 'XTickLabel' property as you specified in your example code. Note that the displayed tick labels do not correspond to the values of the ticks. To avoid this, always set both the 'XTick' and 'XTickLabel' properties together, and when changing back to 'auto' mode for tick placement and labeling, make sure both the 'XTicKMode' and 'XTickLabelMode' are 'auto'. See the MATLAB documentation for 'Axes Properties' for more information.
The behavior of oaxes is identical to the MATLAB axes object in this regard. So if you want to put tick labels at specified locations, set both the 'XTick' and 'XTickLabel' properties of the oaxes object, or just set the 'XTick' property and make sure 'XTickLabelMode' is set to 'auto' (the default). Note that the default behavior of oaxes ticks is to mirror the parent axes tick values ('XTickMode' is set to 'parent' by default). So, unlike the tick label text properties, any changes you make to the parent axes tick values are copied to the oaxes ticks. If you set the 'XTick' property to your own values, 'XTickMode' changes to 'manual'. You can also set it to 'auto' to have oaxes calculate the tick placement rather than copy the parent axes. See the oaxes documentation for more information.

Also note that your example code has errors in the final two 'set' statements - where it reads:


it should say:


Mukilan D

Very good code and also it would be very useful to me. It gave me what I expected. But I could not change the XTicks and YTicks and their labels and also particularly could not change the fontname and fontsize. I have tried with a simple example which is as follows.
x = -pi:0.01:pi
X = x';
y = sin(x);
Y = y'

plot(X,Y,'Linewidth',2);grid on;
oa = oaxes;
oaxes('YColor',[0 0.5 0],'LineWidth',2)
oaxes('XColor',[0 0.5 0],'LineWidth',2)
set(get(oa,'hXLabel'),'fontname','Times New Roman','fontweight','bold','FontSize',12);
set(get(oa,'hYLabel'),'fontname','Times New Roman','fontweight','bold','FontSize',12);
set(gca('XTickLabel'),{'-5','-4','-3','-2','-1','0','1','2','3','4','5'},'fontname','Times New Roman','fontweight','bold','FontSize',20)
set(gca('YTickLabel'),{'1','-0.8','-0.6','-0.4','-0.2','0','0.2','0.4','0.6','0.8','1'},'fontname','Times New Roman','fontweight','bold','FontSize',20)
legend('Sine Wave',2)


John Barber

John Barber (view profile)


Thanks for the feedback - I'll take a look at it. For presentation-quality graphics, you might want to try using export_fig to save your figures (link: ).



It seems that arrows dispear when a figure is saved as a pdf file with the "print" function in MATLAB.
Could you check this?

Thank you.


Dan Knudsen

Thank you very much for this code! Works well on a variety of applications in 2009b (v7.9.0.529), though I haven't tested all features.

Dan Knudsen

John Barber

John Barber (view profile)


Thanks for the feedback. I'll have a new version posted shortly to address the bug.

The axis labels are implemented similarly to the labels for a normal axes. There are two methods to control the display of the axis labels:

1) Set the 'XLabel', etc. property of the oaxes object. This property is a dummy property that is copied to the 'String' properties of the actual label objects. Because there are labels for both the positive and negative sides of each axis, the 'XLabel' property should be specified as a 2x1 cell array. Use the empty string to suppress display of a particular label.

2) Access the label objects directly using their handles. The handles can be found in the 'hXLabel', etc. properties of the oaxes object. As with the 'XLabel' property, 'hXLabel' contains two handles, one for the positive and one for the negative axis label. Using the handles, you can set text size, font, or any other text object property of each label. Note that the labels will be re-created if you delete the label objects. Set the label to the empty string to hide it.

I'll consider adding an 'off' option to the 'AxisLabelLocation' property in a future update.



I got an error message when trying 'arrow' 'off', simply by typing in:

>> oaxes('arrow','off')
??? Index exceeds matrix dimensions.

Error in ==> oaxes at 643
OA = customplots.oaxes(hAx,pvPairs);

My Matlab version is

Also, I miss an option to switch off end axis notation. I can set AxisLabelLocation to end or side, but not to off. It would also be great to be able to set the tags that are written to the ends of the axes, something like XAxisLabel etc., and to determine whether they should come on both sides or only on the positive side.

- Christian



- Fixed bug when parent axes and figure have different background colors
- Fixed error when deleting an oaxes with 'HideParentAxesMode' set to 'color'
- Fixed tick label text properties bugs


- Bug fixes
- Improved redraw speed
- Improved appearance of minor ticks


- Minor bug fix


- Several minor bug fixes
- Removed unneeded code from constructor method


- Full object-oriented version
- 'Extend' limits mode, internal tick calculation, other new features
- Improved graphics refresh speed


- Properties can be accessed using set/get
- Oaxes responds automatically to property changes
- See the release notes for more details


Several bug fixes, improved text alignment, added new properties, improved help text. See the release notes in the help text for a full description.

MATLAB Release
MATLAB 7.10 (R2010a)

Inspired by: axescenter

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video