Plotting Chart With 2 X Axes and 2 Y Axes

Hi there,
I am trying to plot various curves using semilogx along with the line of best fit. I also want to plot some other plots of semilogx on different axes (but in the same figure). I have:
ARI = ones(n,1)./P; % Average Return Interval 1/P
semilogx((ARI), Q);
p_1 = polyfit(log(ARI),Q,1); % Linear best fit
f_1 = polyval(p_1,log(ARI));
hold on
ax1 = gca; % Axis for Linear Fit
ax1.XColor = 'r';
ax1.YColor = 'r';
ax1_pos = ax1.Position; % Position of first axes
ax2 = axes('Position', ax1_pos, 'XAxisLocation','top','YAxisLocation',"right",'Color', 'none'); % Create the second axis
semilogx(ARI, f_1, '--r');
Q_100yr = polyval(p_1, log(100)) % Q value for 1 in 100 year
hold off
For some reason when I try to create the second axis, the position of the axis is not as I would like and I lose my original log curve. It ends up looking like this:
Could someone help me to get the 2 axes working.
Thanks in advance,
Brian

 Accepted Answer

Adam Danz
Adam Danz on 26 May 2020
Edited: Adam Danz on 26 May 2020
In the example plot provided in the question, the x axis is the same for both pairs of axes. To use a left and right axes with the same x axis, se yyaxis.
ARI = ones(n,1)./P; % Average Return Interval 1/P
yyaxis left
semilogx((ARI), Q);
yyaxis right
p_1 = polyfit(log(ARI),Q,1); % Linear best fit
f_1 = polyval(p_1,log(ARI));
semilogx(ARI, f_1, '--r');
Q_100yr = polyval(p_1, log(100)) % Q value for 1 in 100 year

6 Comments

Hi Adam,
I was trying to set up my axes in a similar way to this example: https://au.mathworks.com/help/matlab/creating_plots/graph-with-multiple-x-axes-and-y-axes.html
I have worked on it further and have almost got the graph looking how I would like.
So I'm not sure if yyaxis right is necessary. So far I have:
clf
ARI = ones(n,1)./P;% Average Return Interval 1/P
figure
semilogx((ARI), Q);
p_1 = polyfit(log(ARI),Q,1); % Linear best fit
f_1 = polyval(p_1,log(ARI));
hold on
ax1 = gca; % Axis for Linear Fit
ax1.XColor = 'r';
ax1.YColor = 'r';
ax1_pos = ax1.Position; % Position of first axes
semilogx(ARI, f_1, '--r');
Q_100yr = polyval(p_1, log(100)) % Q value for 1 in 100 year
The following figure is fine for the log curve and line of best fit.
Then I'm trying to plot another log curve, with a y axes on rhs and x axes on the top. I have:
Fx = ones(n,1)-P;
y = -log(-log(Fx));
ax2 = axes('Position', ax1_pos ,'XAxisLocation','top','YAxisLocation','right','Color', 'none');
line(y,Fx,'Parent',ax2,'Color','k')
I then get the following:
I would like to change the chart in the following ways:
  • Instead of using line, I would like to have a semilogx plot so that the top x axis would be similar to the bottom.
  • On the bottom and top x axes change the formatting, so that its not scientific and to show some of the intermediate numbers.
I have then have more curves to plot, so the plan is to plot all the curves of estimation using "method 1" on axis 1 and all the curves using "method 2" on axis 2. I would then match all the colours of the curves to their respective axes and just change some other formatting so that they can be distinguished.
Thanks again for any help,
Brian
Then example in your question shows the same x-scale for both axes. It's important to describe that you also want different x axes in your question since that changes the solution.
To change the upper x axis to log scale,
ax2.XScale = 'log';
Lastly, showing more ticks on a log scale can get messy. But if you want to have your cake (the log scale) and eat it, too (add more ticks), this line below defines 6 total ticks between the min and max x-axis-limits.
ax.XTick = logspace(log10(min(xlim(ax))), log10(max(xlim(ax))), 6);
Thanks Adam,
I will accept and start a new thread to discuss further some other queries I had.
Glad I could help. If the additional questions are related to this topic, I don't mind continuing the conversation here or in another thread.
Ok well regarding the formatting of the axes. I didn't really want to add more ticks but rather to just change the formatting so that 10^0 would read 1 etc and perhaps just add a few numbers in between where there are existing ticks so we could have 1, 5, 10.
If this is too complex then I won't worry because its not that important.
Thanks,
Brian
I'm assuming you want to maintain the log scale. Otherwise, you could just use plot instead of semilogx. Or,
ax = gca();
ax.XScale = 'linear'; % = 'log' to switch back to log scale
Here's how to change the x tick format from exponential to their log10 values.
ax.XTick = ax.XTick; % important to set the xtick first
ax.XTickLabel = cellstr(num2str(ax.XTick'));
Here's how to specify the number of ticks along the x axis in log space. Note that the ticks here are rounded to the nearest 10th but you can adapt as needed. The first line below produces 6 tics spanning the range of the x axis.
xl = xlim(ax); % xlim cannot contain 0, of course.
newTicks = logspace(log10(xl(1)), log10(xl(2)), 6);
ax.XTick = newTicks;
ax.XTickLabel = cellstr(sprintf('%.1f\n',ax.XTick));
ax.XMinorTick = 'off'; %Turn off minor ticks

Sign in to comment.

More Answers (1)

Hi Adam,
I have following code to calculate the expected Q value for 100yr event.
ARI_Weibull = ones(n,1)./P_Weibull;% Average Return Interval 1/P
figure
semilogx((ARI_Weibull), Q, 'r');
p_1 = polyfit(log(ARI_Weibull),Q,1); % Linear best fit
f_1 = polyval(p_1,log(ARI_Weibull));
hold on
% ax1 = gca; % Axis for Linear Fit
% ax1.XColor = 'r';
% ax1.YColor = 'r';
% ax1_pos = ax1.Position; % Position of first axes
semilogx(ARI_Weibull,f_1,'--r');
Q_100yr = polyval(p_1, log(100)) % Q value for 1 in 100 year
xline(log(100)) ;
hold off
For the Q_100yr we get 1.1042e4. Then I thought when I plot xline(log(100)) this would correspond to that Q value on the line of best fit but it doesn't. Do you know where I'm going wrong?

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!