How to insert two X axis in a Matlab a plot
Asked Answered
F

3

16

I would like create a Matlab figure with a double X axis (m/s and km/h) with the same plot.

I have found plotyy and - in Matlab reposity - plotyyy, but I am looking for:

  1. A double X axis.
  2. Together below the plot.

My code is very simple:

stem(M(:, 1) .* 3.6, M(:, 3));

grid on

xlabel('Speed (km/h)');
ylabel('Samples');

M(:, 1) is the speed (in m/s), and M(:, 3) is the data.

I would like only a second line, in the bottom, with the speeds in m/s.

Femineity answered 23/6, 2015 at 17:20 Comment(1)
If you can live with the second x-axis on the top, then just apply this solution and substitute all y with x. If you really want both together on the bottom, I need to disappoint you, it's gonna be real pain in the ass to get that close to an acceptable fashion. I'd recommend, use the the linked solution and just move down the top axis in post processing with inkscape, Illustrator etc. You save yourself a lot of trouble.Sclerenchyma
P
19

You can do something like the following. In comparison to the solution of @Benoit_11 I do use the normal Matlab labels and refer to both axes with handles so the assignments are explicit.

Example Plot

The following code creates an empty x-axis b with the units m/s with a negligible height. After this, the actual plot is drawn in a second axes a located a bit above the other axes and with units km/h. To plot on a specific axes, insert the axes-handle as the first argument of stem. The conversion from m/s to km/h is directly written in the call to stem. Finally, it's needed to set the xlim-property of the both axes to the same values.

% experimental data
M(:,1) = [ 0,  1,  2,  3,  4,  5];
M(:,3) = [12, 10, 15, 12, 11, 13];

% get bounds
xmaxa = max(M(:,1))*3.6;    % km/h
xmaxb = max(M(:,1));        % m/s


figure;

% axis for m/s
b=axes('Position',[.1 .1 .8 1e-12]);
set(b,'Units','normalized');
set(b,'Color','none');

% axis for km/h with stem-plot
a=axes('Position',[.1 .2 .8 .7]);
set(a,'Units','normalized');
stem(a,M(:,1).*3.6, M(:,3));

% set limits and labels
set(a,'xlim',[0 xmaxa]);
set(b,'xlim',[0 xmaxb]);
xlabel(a,'Speed (km/h)')
xlabel(b,'Speed (m/s)')
ylabel(a,'Samples');
title(a,'Double x-axis plot');
Polish answered 23/6, 2015 at 18:3 Comment(3)
I have inserted a feature in your code for the xlim. I write: XT = [min(get(a, 'XTick')) max(get(a, 'XTick'))]; and after I set the limits with set(a, 'xlim', XT); and set(b, 'xlim', XT./3.6);. With this operation I do not force the min 'xlim' to zero.Femineity
Code explanation: With this, a second empty x-axis (b, m/s) with almost zero height (1e-12) is drawn under the one used for the actual plot. Please note that the positions of both axes are manually set to have the same x-position and width, but different y-position (a is set to be above b). In any case, note that you have to use the upper axis for your plots, even if you need to convert the x-values first.Sorrel
@Sorrel That's correct. I just added some explanation.Polish
E
9

As a very simple alternative you could also create a 2nd axis (transparent) and put it below the first one so that you only see the x axis.

Example:

clear
clc
close all

x = 1:10;

x2 = x/3.6;

y = rand(size(x));

hP1 = plot(x,y);

a1Pos = get(gca,'Position');

%// Place axis 2 below the 1st.
ax2 = axes('Position',[a1Pos(1) a1Pos(2)-.05 a1Pos(3) a1Pos(4)],'Color','none','YTick',[],'YTickLabel',[]);

%// Adjust limits
xlim([min(x2(:)) max(x2(:))])

text(2.85,0 ,'m/s','FontSize',14,'Color','r')
text(2.85,.05 ,'km/h','FontSize',14,'Color','r')

Output:

enter image description here

Then you can manually add the x labels for each unit, in different color for example.

Embarrassment answered 23/6, 2015 at 17:50 Comment(0)
E
-1

The best way i can think to do it is to use 2 plots, for example, you can split the plot into a large and small section by doing something like this:

subplot(100, 1, 1:99) // plot your graph as you normally would
plot(...

subplot(100, 1, 100) // Plot a really small plot to get the axis
plot(...)
b = axis()
axis([b(1:2), 0, 0]) // set the y axis to really small

This is untested, you might need to fiddle around a little but it should hopefully put you on the right track.

Exemplary answered 23/6, 2015 at 17:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.