# Multiple Axis Scales

72 views (last 30 days)
Keith Lindsay on 17 Aug 2011
Edited: Terrance Frangakis on 22 Feb 2018
I recall that Matlab is able to label a plot axis (say, x) with multiple scale markings (knots, miles per hour, meters per second) as "stacked" rows, but can't figure out where in the help docs it shows how to do this. For clarity
x-axis-----------------------------------------
Knots 0 50 100 etc
MPH 0 50 100 etc
m/s 0 25 50 etc
Also, I'd like to create a horizontal legend of more than one row (or vertical legend with more than one column). Any hints?
Any help is much appreciated.

John Barber on 17 Aug 2011
For the legend, use one of the File Exchange 'Enhanced Legends':
As far as I know, there isn't a built-in way to do multiple scale markings on an axis. The MATLAB function plotyy creates a pair of overlapping axes allowing you to plot multiple curves with different y-axis scales, etc. See the documentation for the plotyy function for more info. There are also several routines available on the File Exchange that extend/enhance this behavior, including the x-axis. Try one or more of the following:
If these don't work, the code they contain might give you an idea of how to get started. If you want a quick and dirty solution, simply create custom XTicks and XTickLabels at the locations you want, then add additional text objects to account for the lower rows/scales. Here's an example to get you started:
% Create a plot:
plot([1 50 100],[5 10 12],'b-o')
% Set XTicks at desired locations for both km/h and mph:
set(gca,'xtick',[0 20 32.1869 40 60 64.3738 80 96.5606 100])
% Set XTickLabels at km/h locations, leave blank for mph:
set(gca,'xticklabel',{'0','20','','40','60','','80','','100'})
% Create text objects for the mph labels:
text([0; 32.1869; 64.3738; 96.5606],[4.4; 4.4; 4.4; 4.4],{'0','20','40','60'},'color','r','horizontalalignment','center')
% Create text objects for 'km/h' and 'mph':
text(-3,4.8,'km/h','horizontalalignment','right')
text(-3,4.4,'mph','horizontalalignment','right','color','r')
Note that you have to determine the y positions of the text objects yourself, which can be a hassle. Another alternative would be to use one of the several File Exchange submissions that allows for customized ticklabels, which should allow you to create multi-line entries.

Keith Lindsay on 17 Aug 2011
Thanks, John!!

Terrance Frangakis on 22 Feb 2018
Edited: Terrance Frangakis on 22 Feb 2018
I have a simple workaround. In my case, I wanted the secondary x axis to have the inverse of values of the primary x axis (wavenumber on primary axis and wavelength on the secondary axis). The following example shows how I achieved this.
x1=[1:8];
y1=[1 6 2 4 3 1 2 3];
figure
plot(x1,y1);
ax1=gca;
grid
xlabel('Primary axis label')
ylabel('Value')
ax1_pos = get(ax1,'Position');
ax1_label=get(ax1,'XTick');
ax2 = axes('Position',ax1_pos,...
'XAxisLocation','top',...
'YTick',[],...
'XLim',[1 length(x1)],...
'XTickLabel',str2num(sprintf('%.2f ',1./ax1_label)),...
'XLabel','Secondary axis label',...
'Color','none');
The secondary axis needs to know how many xticks there are and what the xticklabels are. In my case, I used a simple element by element inversion, and formatted it to two decimal places. You can vary the number of ticks and labels. The number of labels can be altered by including the 'XTick' parameter in the axes command, by setting it to the same values as the primary axis 'XTick' array, and then changing the labels by the 'XTickLabel' parameter. The 'XTickLabel' array must have the same number of elements as the 'XTick' array.
For example, a new XTick array can be specified with additional entries, and the ax2 statement modified to add additional labels, as follows:
xt2=[1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8];
ax2 = axes('Position',ax1_pos,...
'XAxisLocation','top',...
'YTick',[],...
'XLim',[1 length(x1)],...
'XTick', [1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8],
'XTickLabel',str2num(sprintf('%.2f ',1./xt2)),...
'XLabel','Secondary axis label',...
'Color','none');
The labels may also be explicitly stated in the 'XTickLabel' parameter, rather than make use of a function, if that is more appropriate.