MATLAB: Plotting double bottom x-axis
Asked Answered
V

2

8

I'm trying to plot double bottom x-axis according to the figure after the jump:

enter image description here

It is a semilogx-plot in hours with additional specific ticks representing minutes, months and years. How do I create these additional ticks?

Verlaverlee answered 29/4, 2014 at 14:5 Comment(0)
I
6

You can use Victor May's approach to overlay a secondary axes, but this needs more tweaking to actually work.

First, let's recreate the basic plot:

clear, close
time = [1/60, 1, 24, 24*7, 24*30, 24*30*6, 24*365, 24*365*10];
r = [110, 90, 80, 75, 70, 65, 63, 60];

% plot the data
semilogx(time, r, 'o-')

% adjust ticks and format of primary axes
xlim([0.005 1e6])
ylim([0 140])
tick = 10 .^ (-2 : 6);
set(gca, 'XTick', tick)
set(gca, 'XTickLabel', arrayfun(@num2str, tick, 'UniformOutput', false))
set(gca, 'XMinorTick', 'off')
set(gca, 'TickDir', 'out')

enter image description here

Overlaying a secondary axes only works properly if it has the same position, size, axis limits, and scale type as the primary, and if its background is transparent (otherwise the data become hidden):

% put matching secondary axes on top with transparent background
pos = get(gca, 'Position');
axes('Position', pos)
set(gca, 'Color', 'none')
xlim([0.005 1e6])
ylim([0 140])
set(gca, 'XScale', 'log')
set(gca, 'XMinorTick', 'off')
set(gca, 'TickDir', 'out')

Giving it the proper ticks and tick labels

% adjust ticks
set(gca, 'YTick', [])
set(gca, 'XTick', time)
label = {'1 min', '1 hour', '24 hours', '1 week', '1 month', '6 months', '1 year', '10 years'};
set(gca, 'XTickLabel', label)

results in

enter image description here

– not really what we want.

With a trick we can let the ticks and tick labels of the secondary axes go inside...

% tinker with it
set(gca, 'XAxisLocation', 'top')
pos(4) = eps * pos(4);
set(gca, 'Position', pos)

enter image description here

...but that's still not really what we want.


A different strategy: Let's not overlay axes, but put the additional ticks in ourselves!

label = {'1 min', '1 hour', '24 hours', '1 week', '1 month', '6 months', '1 year', '10 years'};
line([time', time'], [0 2], 'Color', 'k')
text(time, 4 * ones(size(time)), label, 'Rotation', 90, 'VerticalAlignment', 'middle')

The result

enter image description here

is still not perfect, but useable.

Ingravescent answered 29/4, 2014 at 19:16 Comment(0)
I
2

You can do this by adding another axes object to the plot and then setting the properties of its tick marks. Something like this:

close all
plot(1:10, 1:10)
set(gca,'XTick',[1:2:10])
haxes1 = gca;
set(haxes1, 'TickDir', 'out')
haxes1_pos = get(haxes1,'Position'); % store position of first axes
haxes2 = axes('Position',haxes1_pos);
set(gca, 'Color', 'none')
set(haxes2, 'YTick', [])
set(haxes2, 'XTickMode', 'manual');
set(haxes2, 'XTick', [ 0.1 0.8])
set(haxes2, 'TickDir', 'in')

In addition to the code in this example, you will have to edit the tick labels and axis range of the additional axes object. See here for reference on the XLim and XTickLabel properties which do that.

MATLAB doesn't currently support tick labels inside the axes. A 3rd party function that handles this can be found here.

Imperial answered 29/4, 2014 at 14:18 Comment(3)
One problem: this way you get ticks to the inside but not tick labels to the inside.Ingravescent
Also, in the end result the originally plotted data are invisible.Ingravescent
I've addressed both comments in my answer.Imperial

© 2022 - 2024 — McMap. All rights reserved.