Asked by Octavian
on 5 Dec 2013

Dear All,

I have three sets of data (y1,2,3), and I want to plot them on a semilogarithmic (y) scale using the same x scale, but I want to use different ticks and tick labels for y1 and y2 (bottom) and y3 (top)x axes, generalizing it would be two x scales. I tried plotxx but linespec for line vs semilogy are not the same, so I cannot adapt plotxx for my case.

Based on prior posts, I tried this:

% import data into matlab

y1 = zeros(14,1);

y2 = zeros(10,1);

y3 = zeros(14,1);

x = 1:14;

% paste data in y1 (miss by distance), y2 (miss by indiv amplitude), y3 (reg),

% first, plot individual y data using editor to get an idea about ylim

% code break

set (0, 'DefaultAxesFontSize', 8,'DefaultAxesFontName', 'Times');

figure;

set (gcf, 'Units', 'centimeter');

pos = get (gcf, 'Position');

pos(3) = 10;

pos(4) = 8;

set (gcf, 'Position', pos);

set (gca, 'Units', 'centimeter');

set (gca, 'Position', [1.5 1.2 8 5]);)

h1 = semilogy(x,y1,'.r','MarkerSize',6);

hold on;

h2 = semilogy(x(1:10),y2,'xb','MarkerFaceColor','b','MarkerSize',8);

hold on;

h3 = semilogy(x,y3,'ok','MarkerSize',5);

hold off;

H1 = gca;

set(H1,'Xlim',[0.5 14.5]);

set(H1,'Ylim',[10^(-2) 10^3]);

set(H1,'XTick',1:14);

set(H1,'XTickLabel',{'0','5','10','15','20','25','30','35','40','45','50','55','60','65'});

box('on');

set(H1,'tickdir','out');

ax=axis;

H2=axes('position', get(H1,'position'));

axis(ax);

set(H2,'XAxisLocation','top')

set(H2,'XTick',1:14);

set(H2,'XTickLabel',{'reg1cm_1','reg1cm_2','reg1cm_3','reg1cm_4','reg1.5cm_1','reg1.5cm_2','reg1.5cm_3','reg1.5cm_4','reg1.5cm_5','reg1.5cm_6','reg1.5cm_7','reg1.5cm_8','reg1.5cm_9'});

set(H2,'YAxisLocation','right');

set(H2,'yticklabel','');

The top tick labels are not displayed using the above, please advise.

Many thanks,

Octavian

Answer by dpb
on 5 Dec 2013

Accepted Answer

As surmised above, you never set the x-axis limits on the second axes...

...

H2=axes('position', get(H1,'position'));

set(H2,'XAxisLocation','top')

% Following line is missing...so the default limits are [0 1]

set(H2,'Xlim',[0.5 14.5]);

...

Octavian
on 5 Dec 2013

Thank you, dpb,

Sorry about the long post, I do not do this that often. Using your suggestion, it works if a start my script from the plot command:

x = 1:14; y1 = randn(14,1); y2 = randn(10,1); y3 = randn(14,1);

h1 = semilogy(x,y1,'.r','MarkerSize',6); hold on;

h2 = semilogy(x(1:10),y2,'xb','MarkerFaceColor','b','MarkerSize',8); hold on;

h3 = semilogy(x,y3,'ok','MarkerSize',5); hold off;

H1 = gca;

set(H1,'Xlim',[0.5 14.5]);

set(H1,'Ylim',[10^(-2) 10^3]);

set(H1,'XTick',1:14);

set(H1,'XTickLabel',{'0','5','10','15','20','25','30','35','40','45','50','55','60','65'});

box('on');

set(H1,'tickdir','out');

ax=axis;

H2=axes('Position',get(H1,'Position'));

set(H2,'Color','none');

axis(ax);

set(H2,'XAxisLocation','top');

set(H2,'Xlim',[0.5 14.5]);

set(H2,'XTick',1:14);

set(H2,'XTickLabel',{'reg','reg1cm_1','reg1cm_2','reg1cm_3','reg1cm_4','reg1.5cm_1','reg1.5cm_2','reg1.5cm_3','reg1.5cm_4','reg1.5cm_5','reg1.5cm_6','reg1.5cm_7','reg1.5cm_8','reg1.5cm_9'});

set(H2,'YAxisLocation','right');

set(H2,'Ytick',[]);

set(H2,'tickdir','out');

1) All good for now, although I would like to find a way to increase the distance between the top xticklabels (H2) and the upper x axis (H2), without increasing the size of Xticks.

2) A second issue, more important, is that H2 is not displayed(!) if I set the figure and gca positions prior to plotting, with the following (as in my prior email:

set (0, 'DefaultAxesFontSize', 8,'DefaultAxesFontName', 'Times');

figure;

set (gcf, 'Units', 'centimeter');

pos = get (gcf, 'Position');

pos(3) = 10; pos(4) = 8;

set (gcf, 'Position', pos);

set (gca, 'Units', 'centimeter');

set (gca, 'Position', [1.5 1.2 8 5]););

I need to scale the picture from the outset to generate readily publishable plots. I guess fixing the gca (H1) position at the beginning may be the culprit, but I cannot figure out a workaround.

Please advise, Octavian

dpb
on 5 Dec 2013

I've got meeting this evening so no time to delve deeply but a quick look-see makes me wonder what you're trying to do with

set(H2,'Color','none');

That, I'd guess, makes H2 disappear. There may be something else in the ranges, etc., that's a problem, too, but pretty sure you don't want that line in there...

Sign in to comment.

Answer by Octavian
on 6 Dec 2013

Dear dpb,

set(H2,'Color','none');

is necessary, otherwise data plots are obscured during the second x axis (top, H2) definition. In the end, you were right in that is was a scaling issue, as the figure and axis properties were defined initially in cm (to create a plot 'as is', sized for publication in a two-column article page), whereas the extra x axis at the top (H2) was read in normalized units. Here is a sample code that seems to serve the purpose of creating two x axes (bottom and top) when plotting data with semilogy (or for that matter, other plot functions, such as plot):

...

y1 = randn(14,1); y2 = randn(10,1); y3 = randn(14,1); % create data vectors

x =1:14; % x = data point vector

% create figure defaults for publication

set (0, 'DefaultAxesFontSize', 8,'DefaultAxesFontName', 'Times');

figure;

set (gcf, 'Units', 'centimeter');

pos = get (gcf, 'Position');

pos(3) = 10;

pos(4) = 8;

set (gcf, 'Position', pos);

set (gca, 'Units', 'centimeter');

set (gca, 'Position', [1.5 1.2 8 5]);

% plot data as line with markers

h1 = semilogy(x,y1,'-.r','MarkerSize',6); % can be replaced by other plot functions

hold on;

h2 = semilogy(x(1:10),y2,'-xb','MarkerFaceColor','b','MarkerSize',8);

hold on;

h3 = semilogy(x,y3,'-ok','MarkerSize',5);

hold off;

set(gca,'Xlim',[0.5 14.5]);

set(gca,'Ylim',[10^(-2) 10^3]);

set(gca,'XTick',1:14);

set(gca,'XTickLabel',{'0','5','10','15','20','25','30','35','40','45','50','55','60','65'});

set(gca,'YTickLabel',{'0.01','0.1','1','10','100','1000'});

box('on');

set(gca,'tickdir','out');

% create second, top x axis

H1 = gca;

H2 = axes('Units', get(H1,'Units'));

set(H2, 'Position',[1.5 1.2 8 5]); % same position as H1

set(H2,'XAxisLocation','top');

set(H2,'YAxisLocation','right');

set(H2,'color','none');

set(H2,'Xlim',[0.5 14.5]);

set(H2,'XTick',1:14);

set(H2,'XTickLabel',{'0.5','1','1','1','1','1.5','1.5','1.5','1.5','1.5','1.5','1.5','1.5','1.5'});

set(H2,'Ytick',[]);

set(H2,'tickdir','out');

...

Likely is not the most efficient way, but one of many,

Thank you,

Octavian

dpb
on 6 Dec 2013

Good on ya' for finding it...I had a meeting last night so had no opportunity to look any further. I realized later what the 'none' was for, indeed; it was just a gut reaction when glancing thru the code first pass.

I didn't try but another way you might look at that might save some machinations would be to use plotyy as a starting point then just change the locations of the RH x-axis. If, as in your case, you actually want all the data on the LH axis, simply plot a couple of NaN vectors/points on the RH if it is unhappy w/ an empty argument list for the second axes.

I think there's a plotxx or similarly named submission on the File Exchange as well you might look for; as a general rule when you have some specialized graphing need like this it's worth looking at FEX as somebody else has likely had the need before, too.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## dpb (view profile)

Direct link to this comment:https://www.mathworks.com/matlabcentral/answers/108716-how-to-plot-semilogy-on-two-axes#comment_183732

Sign in to comment.