MATLAB Answers

0

how to plot semilogy on two axes

Asked by Octavian on 5 Dec 2013
Latest activity Commented on by dpb
on 6 Dec 2013
Accepted Answer by dpb
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

  1 Comment

Truncate the example to the barest number of lines that shows the problem and include sample data as well so it's trivial for a reader to recreate the issue locally. Don't expect donated time/help to finish the job of asking the question for you.
W/o extensively reading the code to try to discern a problem, the first and most likely reason for customized tick lablels to not show up on an axis is that the tick values aren't in the range of the appropriate x-axis limits for the axes object in question.

Sign in to comment.

2 Answers

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]);
...

  2 Comments

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
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

  1 Comment

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.