Plotting two x axis in one plot, but both at the bottom.

Hi I am looking for a way to plot two x axis but both x-axis has to be in the bottom. Like shown here in the picture. The only thing I can find is where the two x-axis are on top and bottom of the plot, where I want them both on bottom.

2 件のコメント

Adam
Adam 2017 年 6 月 14 日
You forgot to attach a picture
Mikkel
Mikkel 2017 年 6 月 16 日

Here is the picture, hope you can help me, it's the same plot but with different x axis shown.

サインインしてコメントする。

回答 (3 件)

dpb
dpb 2017 年 6 月 14 日
編集済み: dpb 2017 年 6 月 16 日

1 投票

See answer I gave <4 Y Axes> that illustrates adding a second y-axes on each the LH and RH axes. Simply make the adjustment in height and bottom locations (which are respectively, pos(2)/pos(4) instead of pos(1)/pos(3) in the position vector.
That technique makes the second x-axis small in height so you still would have to plot the data on the first in its scale but set the limits on the second to reflect actual.
Without the picture of what you're specifically trying to duplicate, I'm having difficulty in otherwise how you would make this work...do attach the figure, it'll help.
ADDENDUM It really isn't difficult; just follow the path outlined at the previous answer...
hAX=axes; % first axes, save handle
pos=get(hAX,'position') % get the position vector
pos =
0.1300 0.1100 0.7750 0.8150
pos1=pos(2); % save the original bottom position
pos(2)=pos(2)+pos1; pos(4)=pos(4)-pos1; % raise bottom/reduce height->same overall upper position
set(hAX,'position',pos) % and resize first axes
pos(2)=pos1; pos(4)=0.01; % reset bottom to original and small height
hAX(2)=axes('position',pos,'color','none'); % and create the second
ylabel(hAX(1),'Axes 1')
xlabel(hAX(1),'Axes 1')
xlabel(hAX(2),'Axes 2')
set(haX(2),'xcolor','r','ycolor','r')

7 件のコメント

Mikkel
Mikkel 2017 年 6 月 16 日

Its on the right path, but its the x-axis I need to change.

Adam
Adam 2017 年 6 月 16 日
You should still be able to apply the same idea, there's is nothing specific to y-axis in it other than the pos(1), pos(3) etc that you will obviously have to change to pos(2) and pos(4) and work out sensible values for the maths of.
dpb
dpb 2017 年 6 月 16 日
Yes, that's what I imagined, the linked-to answer is the solution, you'll just modify the bottom and height of the axis position vector instead of left and width.
The 'position' vector components are [left,bottom,width,height]
Min Oo
Min Oo 2018 年 9 月 27 日
How do I get these two line exactly the same by adjusting the second x-axis.? Thanks.
dpb
dpb 2018 年 9 月 28 日
編集済み: dpb 2018 年 9 月 30 日
Sorry, don't understand the question? The above figure with Axes1 and Axes2 were built with the code I supplied at the above Answer; they are the same length as they are; the adjustment that is made is to Axes1 to shorten its height by raising bottom position and compensating shorter height value to give room for Axes2 and then set the second to the same bottom position as was Axes1 by default but then shorten its height to essentially zero (0.01).
Tanvir Alam
Tanvir Alam 2021 年 6 月 5 日
編集済み: Walter Roberson 2026 年 1 月 18 日
Hello Dpd!!
how can i plot now after typing your code over two different x-axis?
at=axes;
pos=get(at,'position');
pos1=pos(2);
pos(2)=pos(2)*2; pos(4)=pos(4)-(pos1);
set(at,'position',pos)
pos(2)=pos1; pos(4)=.003;
at(2)=axes('position',pos,'color','none');
hold(at(2),'on')
plot(at(2),t2,st)
dpb
dpb 2026 年 1 月 18 日
Don't know what brought this old thread back to the forefront, and mayhaps I didn't see the above back then...
"how can i plot now ... over two different x-axis?"
That's somewhat problematical with MATLAB handle graphics designed as it is -- when you create the second axes but don't give it any height, you can't draw on it as in the original. What has to be done is to do all the plotting on axes at(1) but do a linear transformation of the x data that belongs with the second axes to the coordinates of the first.
at=axes;
pos=get(at,'position');
pos1=pos(2);
pos(2)=pos(2)*2; pos(4)=pos(4)-(pos1);
set(at,'position',pos)
pos(2)=pos1; pos(4)=.003;
at(2)=axes('position',pos,'color','none');
at(2).FontSize=at(1).FontSize;
% make up some sorta' similar data
x=rescale(rand(1,11),0.1,20); y=rescale(1:numel(x),0.1,2);
hB=plot(at(1),x,y,'b-'); % the blue line
at(1).YAxis.Direction='reverse';
Z=10; % "ZOOM" factor
xlim(at(1),[0 40])
xlim(at(2),xlim(at(1))/Z) % zoom bottom axes relative top
ylim(at(1),[0 2])
at(1).YAxis.TickLabelFormat='%0.1f';
hold(at,'on')
hR=plot(at(1),x*Z,y,'r-'); % the red line at Z factor
The x labels can be added to each axes handle.
For the particular instantiation of the random data the zoomed line isn't continuous as in the orginal picture, but that's solely owing to the data itself...the same data would look the same.
I don't know if it possible to perhaps achieve the same effect by having the second axes full height by just not a visible y axes in which case one could use the actual xlim on the second but would have to offset the y values. That's probably more difficult of a scaling problem than the above -- it's simplified owing to the zero origin; it would require the scale+offset linear transformation otherwise. polyfit would work there.

サインインしてコメントする。

ye pyae sone oo
ye pyae sone oo 2020 年 1 月 10 日

0 投票

Hello. Well, the discussion is a little bit old but I think I am facing the same situation, 'Question posed by Mr. Min Oo'. I think I understand his question. Let's say, we have three vectors, x1, x2 and y.
x1 = [0.06, 0.2, 0.4]; % I want to put this in X axis 1
x2 = [9, 28, 58]; % I want to put this in X axis 2
y = [120, 80, 62]; % this is y-axis.
Now, my question is what I should do if I want to have a plot with 2 x-axes, both at the bottom but representing the same for both x1 and x2. Say, at x1 = 0.06, I want x2 = 9 from X axis 2 to be directly under the value x1. I also want each value of x1 and x2 to be exactly the same upper and lower postion of X axis 1 and X axis 2. Is it manageable?
I hope it is clear.
Thanks in advance

6 件のコメント

dpb
dpb 2020 年 1 月 10 日
This is a different question and should be a separate Q?, not posted as Answer to another (albeit somewhat related) Q?.
A quick answer, however, is "no". The relative distance between your x1 and x2 points isn't the same so a linear scaling won't/can't align the three values precisely. You can put arbitrary labels wherever you want them, but it will be lying some to the viewer.
x1(3)/x1(2) = 2 while x2(3)/x2(2) = 29/14 > 2. They're approximately the same, but not identical. Similar differences between other two points-- 3.3333...., vs. 3.11111...
ye pyae sone oo
ye pyae sone oo 2020 年 1 月 10 日
Thank you.
As for the number, sorry for the confusion because I rounded them without any consequent thoughts. I re-checked them in my original calculation and they each have the same ratio for each one, that is, if I don't round them and directly put them into ratio, they show linear relation. In that case, I can put them together, maybe writing like your sample code.
Anyway, thank you for pointing that out :).
Best regards
dpb
dpb 2020 年 1 月 10 日
Yes, then the above should work just fine with actual numbers. If you set the xlim values for each of the two so they have the same comparative width ratios or if you use the actual start/stop endpoints (of course, the latter gives no white space from the first/last datapoints which isn't probably ideal for appearances' sake).
Mckenzie Dice
Mckenzie Dice 2020 年 12 月 4 日
編集済み: dpb 2020 年 12 月 4 日
Perhaps @dpb you could help me also... I want to do a similar thing but I am not having issues of axis plaement, rather I cannot get my values to plot to the correct axis. I have four data sets to plot, and three of them need to plot to the first axis and the last one needs to plot to the secondary axis. But every time I do this the only thing that shows up on the plot is that last data set and it overwrites the first three in every subplot. I think I need a hold off or to hold the axis off somewhere but I do not know where.
figure(20)
FigH= figure('Position', get(0, 'Screensize'));
c=1;
while c<=20
subplot(4,5,c)
plot(av_v(:,c),z_plot, 'r') %first axis
hold on
plot(av_u(:,c),z_plot,'b') %first axis
hold on
plot(averages(:,c),z_plot,'g') %first axis
hold on
xlim([-5,15])
ylabel('height,m')
xlabel('u and v (m/s), t (k)','FontSize',8)
hAx(1)=gca;
hAx(2)=axes('Position',hAx(1).Position,'XAxisLocation','top','YAxisLocation','right');
hold(hAx(2),'on')
plot(avri(c,:),z_plot,'k') %second axis: hAx(2)
xlim([-.05,.15])
xlabel('Richardson Number','FontSize',8)
title(c)
legend('v','u','th','avri')
fig = gcf;
fig.Position(3) = fig.Position(3) + 250;
% add legend
legend('Position',[0.15 0.95 0.01 0.02])
legend('boxoff')
c=c+1;
end
dpb
dpb 2020 年 12 月 5 日
c=1;
while c<=20
subplot(4,5,c)
plot(av_v(:,c),z_plot, 'r') %first axis
hold on
plot(av_u(:,c),z_plot,'b') %first axis
hold on
plot(averages(:,c),z_plot,'g') %first axis
hold on
xlim([-5,15])
ylabel('height,m')
xlabel('u and v (m/s), t (k)','FontSize',8)
hAx(1)=gca;
hAx(2)=axes('Position',hAx(1).Position,'XAxisLocation','top','YAxisLocation','right');
...
Many issues here...
  1. Why use a while instead of just simple counted for loop?
  2. Save the axes handle when you create it with subplot while you're there.
  3. One you've set hold for a given axes, it won't get any "onner" by repeating it. "ON" is "ON"
  4. This Q? posed a different problem that required manually creating the second axis; your case can be solved more simply plotyy with a couple adjustments. Unfortunately, TMW got only half the job done with yyaxis--there is no complementary xxaxis and they went steerage class by not incorporating a second XAxis object.
  5. You go through this loop 20 times but every time you use and then overwrite hAx(1) and hAx(2) instead of keeping a distinct handle to the given plot axes
Very crude, but something more like:
hAx=gobjects(20,2); % allocate axes handles array for L, R
for i=1:20
subplot(4,5,i); % create the subplot
hAx(i,:)=plotyy(av_v(:,c),z_plot, 'r',avri(c,:),z_plot,'k');
hold(hAx(i,1),'on')
plot(av_u(:,c),z_plot,'b')
plot(averages(:,c),z_plot,'g')
xlim(hAx(i,1),[-5,15])
ylabel('height,m')
xlabel('u and v (m/s), t (k)','FontSize',8)
hAx(i,2).XAxisLocation='top';
xlim(hAx(i,2),[-.05,.15])
xlabel(hAx(i,2),'Richardson Number','FontSize',8)
...
% legends and so on here....
end
Kamaka
Kamaka 2026 年 1 月 18 日
The answer is
Plot(x,y1)
hold on
Plot(x,y2)
hold off

サインインしてコメントする。

dpb
dpb 2026 年 1 月 20 日
編集済み: dpb 2026 年 1 月 20 日

0 投票

Had a revelation -- the above to create the two axes can be much easier with subplot or tiledlayout. We'll use the venerable subplot here...
N=8; % number of panes to divide figure into
Z=10; % "ZOOM" factor
hAx=subplot(N,1,1:(N-1)); % divide figure into panes, group N-1 top ones into one
hAx(2)=subplot(N,1,N,'Color','none'); % create the Nth one at bottom
hAx(2).YAxis.Visible='off'; % show its x axis only
hAx(2).FontSize=hAx(1).FontSize; % default is smaller owing to height
% make up some sorta' similar data
x=rescale(rand(1,11),0.1,20); y=rescale(1:numel(x),0.1,2);
hB=plot(hAx(1),x,y,'b-');
hAx(1).YAxis.Direction='reverse';
xlim(hAx(1),[0 40])
xlim(hAx(2),xlim(hAx(1))/Z)
ylim(hAx(1),[0 2])
hAx(1).YAxis.TickLabelFormat='%0.1f';
hold(hAx,'on')
hR=plot(hAx(1),x*Z,y,'r-');
On the comment above about the scaling of the two x axes and polyfit being useful
b=polyfit(xlim(hAx(2)),xlim(hAx(1)),1)
b = 1×2
10 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
gives the coefficients of the scaling needed -- note here the intercept is 0; if one set the origin for either (or both) to something other than 0, then it would not be.

カテゴリ

質問済み:

2017 年 6 月 14 日

編集済み:

dpb
2026 年 1 月 20 日

Community Treasure Hunt

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

Start Hunting!

Translated by