現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
Multiple X axis in different scale, but one y axis
108 ビュー (過去 30 日間)
古いコメントを表示
Hello,
How to Add Multiple X axis in different scale? Please help me? It will look like this:
採用された回答
Adam Danz
2020 年 7 月 28 日
編集済み: Adam Danz
2022 年 4 月 14 日
Matlab does not support mutliple x axes other than the axes at the upper and lower borders of the plot.
One way to include multiple axis units is to create multi-lined x-axis ticks. The upper axis will be your main axis used to plot your data. Then define the axis limits for all additional pseudo-axes and compute the tick values for each pseudo-axis so they align with the x-ticks on the main axis. Use those value to create the multi-lined x-tick labels.
Follow the demo below and adjust it to fit your needs.
Demo
% Set up main axis (on top)
clf()
ax = axes();
ax.XTick = 0:200:2800;
ax.XLim = [0,2800];
% Set axis limits for all other axes
additionalAxisLimits = [...
0, 1400; % axis 2
19.2, 23.4; % axis 3
0.2, 3]; % axis 4
% Compute tick values for each axis to align with main axis
additionalAxisTicks = arrayfun(@(i){linspace(additionalAxisLimits(i,1), ...
additionalAxisLimits(i,2),numel(ax.XTick))}, 1:size(additionalAxisLimits,1));
% Set up multi-line ticks
allTicks = [ax.XTick; cell2mat(additionalAxisTicks')];
tickLabels = compose('%4d\\newline%4d\\newline%.1f\\newline%.1f', allTicks(:).');
% The %4d adds space to the left so the labels are centered.
% You'll need to add "%.1f\\newline" for each row of labels (change formatting as needed).
% Alternatively, you can use the flexible line below that works with any number
% of rows but uses the same formatting for all rows.
% tickLabels = compose(repmat('%.2f\\newline',1,size(allTicks,1)), allTicks(:).');
% Decrease axis height & width to make room for labels
ax.Position(3:4) = ax.Position(3:4) * .75; % Reduced to 75%
ax.Position(2) = ax.Position(2) + .2; % move up
% Add x tick labels
set(ax, 'XTickLabel', tickLabels, 'TickDir', 'out', 'XTickLabelRotation', 0)
% Define each row of labels
ax2 = axes('Position',[sum(ax.Position([1,3]))*1.08, ax.Position(2), .02, 0.001]);
linkprop([ax,ax2],{'TickDir','FontSize'});
axisLabels = {'Distance (t)','Area (m^2)','Cnt from 0 (m)','KB (m)'}; % one for each x-axis
set(ax2,'XTick',0.5,'XLim',[0,1],'XTickLabelRotation',0, 'XTickLabel', strjoin(axisLabels,'\\newline'))
ax2.TickLength(1) = 0.2; % adjust as needed to align ticks between the two axes
Similar examples in the forum
34 件のコメント
Alpha Boy
2020 年 7 月 28 日
% Set up main axis (on top)
ax = axes();
ax.XTick = 4000:5000:30000; %Disp
ax.XLim = [4000,30000];
% Set axis limits for all other axes
additionalAxisLimits = [...
3500, 4500; % axis 2 WPA
0,6; % axis 3 KB
20,30; % axis 4 LCB
30,50; %axis 5 TPC
200, 500; %axis 6 MCTC
0, 50; %axis 7 BMt
100,1500; %axis 8 BMl
20, 250; %axis 9 AM
0, 1; %axis 10 CB
0, 1; %axis 11 CM
0, 1; %axis 12 CP
0, 1; %axis 13 CWP
0, 1]; %axis 14 CVP
Output: :( Help me plz :( :(
Adam Danz
2020 年 7 月 28 日
編集済み: Adam Danz
2020 年 7 月 28 日
I can't see what's wrong without seeing your code.
My guess is that you forgot this transpose,
tickLabels = compose('%4d\\newline%4d\\newline%.1f\\newline%.1f', allTicks(:).');
% ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ^^
If that's not the problem go through your code line by line and compare the results to my version to see where it starts to differ.
Adam Danz
2020 年 7 月 28 日
I can't help without seeing your code. The code you provided in a comment above is incomplete.
Share the relevant section of code.
Alpha Boy
2020 年 7 月 28 日
% Set up main axis (on top)
ax = axes();
ax.XTick = 4000:5000:30000; %Disp
ax.XLim = [4000,30000];
% Set axis limits for all other axes
additionalAxisLimits = [...
3500, 4500; % axis 2 WPA
0,6; % axis 3 KB
20,30; % axis 4 LCB
30,50; %axis 5 TPC
200, 500; %axis 6 MCTC
0, 50; %axis 7 BMt
100,1500; %axis 8 BMl
20, 250; %axis 9 AM
0, 1; %axis 10 CB
0, 1; %axis 11 CM
0, 1; %axis 12 CP
0, 1; %axis 13 CWP
0, 1]; %axis 14 CVP
% Compute tick values for each axis to align with main axis
additionalAxisTicks = arrayfun(@(i){linspace(additionalAxisLimits(i,1), ...
additionalAxisLimits(i,2),numel(ax.XTick))}, 1:size(additionalAxisLimits,1));
% Set up multi-line ticks
allTicks = [ax.XTick; cell2mat(additionalAxisTicks')];
tickLabels = compose('%14d\\newline%14d\\newline%.1f\\newline%.1f', allTicks(:).');
% The %4d adds space to the left so the labels are centered.
% Decrease axis height & width to make room for labels
ax.Position(3:4) = ax.Position(3:4) * .75; % Reduced to 75%
ax.Position(2) = ax.Position(2) + .2; % move up
% Add x tick labels
set(ax, 'XTickLabel', tickLabels, 'TickDir', 'out')
% Define each row of labels
ax2 = axes('Position',[sum(ax.Position([1,3]))*1.1, ax.Position(2), .02, 0]);
linkprop([ax,ax2],{'TickDir','TickLength','FontSize'})
axisLabels = {'Distance (t)','Area (m^2)','Cnt from 0 (m)','KB (m)'}; % one for each x-axis
set(ax2,'XTick',0.5,'XLim',[0,1],'XTickLabel', strjoin(axisLabels,'\\newline'))
Here it is.
Adam Danz
2020 年 7 月 28 日
I see your mistake. You didn't expand the compose() function beyond the 4 rows I have in my demo. It's very important that you go through each line of code to understand what it does so you can learn something and so you can own your work and call it yours.
I've updated my answer to show how to flexibly create the compose() line no matter how many rows are in the tick labels. There are several small changes to my answer that you should look for but here's are the 3 main changes you need to make to your code.
1) replace the old compose() line with this one.
tickLabels = compose(repmat('%.2f\\newline',1,size(allTicks,1)), allTicks(:).');
Note that all of your labels will now have 2 dp.
2) Since you have so many rows of labels, you'll need to shrink the height of your axes even further.
% Decrease axis height & width to make room for labels
ax.Position(3) = ax.Position(3) * .75; % Reduced width to 75%
ax.Position(4) = ax.Position(4) * .40; % Reduced height to 40%
ax.Position(2) = ax.Position(2) + .48; % move up
3) Fill in the rest of the axis labels (see axisLabels variable).
Adam Danz
2020 年 7 月 28 日
By the way, if those axis limits are your real data, you could remove the last 4 rows since they are the same scale. That gives you more space for the plot.
Alpha Boy
2020 年 7 月 28 日
Wow, it works. And at the last moment one last question, How can I get the lines, I mean the graph.
Alpha Boy
2020 年 7 月 28 日
Where, I have to put, grid on?
I have tables, I have values of X and Y axis
How can I put those?
Adam Danz
2020 年 7 月 28 日
The grid command places the vertical and horiztonal grid lines on the axes.
To plot the data, use the plot command. The x-values should be in the same units as your main axes on top (ranging from 4000 to 30000).
If you have trouble plotting, you may want to go through the Matlab Onramp to learn the basics.
Alpha Boy
2020 年 7 月 28 日
I am a newbie in MATLab. I simply plot (x,y). But here, 14 different scale. So I cannot get it. Can you give me some idea for it? I would be greatfull.
Alpha Boy
2020 年 7 月 28 日
% Set up main axis (on top)
ax = axes();
ax.XTick = 4000:5000:30000; %Disp
ax.XLim = [4000,30000];
% Set axis limits for all other axes
additionalAxisLimits = [...
3500, 4500; % axis 2 WPA
0,6; % axis 3 KB
20,30; % axis 4 LCB
30,50; %axis 5 TPC
200, 500; %axis 6 MCTC
0, 50; %axis 7 BMt
100,1500; %axis 8 BMl
20, 250; %axis 9 AM
0, 1;] %axis 10 CB
grid on
draft_y = [2, 4, 6, 8];
%
dispS = [4338.433882, 12602.51994, 20397.27172, 29240.4964];
% dispW = [4338.433882, 12602.51994, 20397.27172, 29240.49644];
% %bmT = [49.934497, 18.50834124, 11.99581801, 8.749939429];
KB = [1.69838, 2.41533, 3.48171, 4.66708];
% %LCB = [29.94300827, 29.8
plot(dispW,draft_y, KB,draft_y)
% Compute tick values for each axis to align with main axis
additionalAxisTicks = arrayfun(@(i){linspace(additionalAxisLimits(i,1), ...
additionalAxisLimits(i,2),numel(ax.XTick))}, 1:size(additionalAxisLimits,1));
% Set up multi-line ticks
allTicks = [ax.XTick; cell2mat(additionalAxisTicks')];
tickLabels = compose(repmat('%.2f\\newline',1,size(allTicks,1)), allTicks(:).');
% The %4d adds space to the left so the labels are centered.
% Decrease axis height & width to make room for labels
% Decrease axis height & width to make room for labels
ax.Position(3) = ax.Position(3) * .75; % Reduced width to 75%
ax.Position(4) = ax.Position(4) * .40; % Reduced height to 40%
ax.Position(2) = ax.Position(2) + .48; % move up
% Add x tick labels
set(ax, 'XTickLabel', tickLabels, 'TickDir', 'out')
% Define each row of labels
ax2 = axes('Position',[sum(ax.Position([1,3]))*1.1, ax.Position(2), 0.2, 0]);
linkprop([ax,ax2],{'TickDir','TickLength','FontSize'})
axisLabels = {'Area (m^2)', 'Distance (t)','Area (m^2)','Cnt from 0 (m)','KB (m)'}; % one for each x-axis
set(ax2,'XTick',0.5,'XLim',[0,1],'XTickLabel', strjoin(axisLabels,'\\newline'))
I only tried 2 out of 14
Alpha Boy
2020 年 7 月 28 日
marked one is not correct!!!, Blue line is ok. how can I plot 14 different scale line??
Adam Danz
2020 年 7 月 28 日
編集済み: Adam Danz
2020 年 7 月 28 日
You're asking me to do your entire project for you. I can help you learn but I will not do your work for you.
You need to normalize all of your x values so they match the scale of your main x axis.
Here's an example. You need to understand the example and apply it to your data.
First, you need to decide the lower and upper bounds of your x-axis range.
ax.XLim = [4000,30000];
Then you need to normalize the x-values to that range. The x values in my demo range from 20 to 30.
x = [22 30 26 25 24 25 25 22];
xBounds = [20,30];
% Normalize to the x-axis limits
xNorm = (x - xBounds(1))/range(xBounds) * range(ax.XLim) + ax.XLim(1);
Now plot your data using xNorm
plot(xNorm, y)
Repeat this for all lines. The y axis values will automatically adjust with the range of your data.
Alpha Boy
2020 年 7 月 28 日
xNorm = (x - xBounds(1))/range(xBounds) * range(ax.XLim) + ax.XLim(1); in this line, what does "(1)" mean?
Alpha Boy
2020 年 7 月 28 日
Sir, Please help me. I am not requesting you to do my project. I simply want to learn. I have stuck with this for last 3 days
Adam Danz
2020 年 7 月 28 日
"in this line, what does "(1)" mean?"
Look at the value of ax.XLim. The (1) selects the first element which is the lower x-limit.
Normalization is when you convert a set of data to a different scale. A well known example is percentages. 0.2, 0.5, 0.8 can be converted to 20%, 50%, 80% by multiplying by 100. Your normalization is a bit more complicated because the data must be scaled to fit within 4000-30000.
"And where I have to write this codes, I mean which lines? at the end?"
You can normalize the data anywhere in your code after the ax.XLim is set.
I suggest doing the plotting after the axes are all set up.
Adam Danz
2022 年 3 月 15 日
My answer does not add a second x-axis. Instead, it adds rows of x-tick-labels to represent additional axes at different scales. You could implement this idea but it would not show a second axis line and the tick intervals would differ. Matlab does not currently offer a method of adding addtional axis rulers (lines) but you could ask a new question or search the forum to find work-arounds.
Adila Nalisa Binti Mohd Roslan
2022 年 3 月 16 日
Thank Adam for claryfication on this issues. However do you have any idea so that I can add second axis like that in Matlab? I would really grateful if you can share the idea. Thank you in advance.
Matthew Mishrikey
2022 年 4 月 14 日
Note, this method does not work with uiaxes.
Unfortunately the newlines don't get rendered, and you end up with just a single line for each tick label.
This is almost the same code as Adams, with uiaxes, and also forcing the label rotation to 0.
% Set up main axis (on top)
clf()
uif = uifigure('HandleVisibility','on');
ax = uiaxes(uif,'Position', [20 100 500 300]);
ax.XTick = 0:200:2800;
ax.XLim = [0,2800];
% Set axis limits for all other axes
additionalAxisLimits = [...
0, 1400; % axis 2
19.2, 23.4; % axis 3
0.2, 3]; % axis 4
% Compute tick values for each axis to align with main axis
additionalAxisTicks = arrayfun(@(i){linspace(additionalAxisLimits(i,1), ...
additionalAxisLimits(i,2),numel(ax.XTick))}, 1:size(additionalAxisLimits,1));
% Set up multi-line ticks
allTicks = [ax.XTick; cell2mat(additionalAxisTicks')];
tickLabels = compose('%4d\\newline%4d\\newline%.1f\\newline%.1f', allTicks(:).');
% The %4d adds space to the left so the labels are centered.
% You'll need to add "%.1f\\newline" for each row of labels (change formatting as needed).
% Alternatively, you can use the flexible line below that works with any number
% of rows but uses the same formatting for all rows.
% tickLabels = compose(repmat('%.2f\\newline',1,size(allTicks,1)), allTicks(:).');
% Decrease axis height & width to make room for labels
ax.Position(3:4) = ax.Position(3:4) * .75; % Reduced to 75%
ax.Position(2) = ax.Position(2) + .2; % move up
% Add x tick labels
set(ax, 'XTickLabel', tickLabels, 'TickDir', 'out','XTickLabelRotation',0)
% Define each row of labels
ax2 = uiaxes(uif,'Position',[sum(ax.Position([1,3]))*1.08, ax.Position(2), .02, 0.001]);
axisLabels = {'Distance (t)','Area (m^2)','Cnt from 0 (m)','KB (m)'}; % one for each x-axis
set(ax2,'XTick',0.5,'XLim',[0,1],'XTickLabel', strjoin(axisLabels,'\\newline'))
ax2.TickLength(1) = 0.2; % adjust as needed to align ticks between the two axes
linkprop([ax,ax2],{'TickDir','FontSize','XTickLabelRotation'});
Adam Danz
2022 年 4 月 14 日
編集済み: Adam Danz
2022 年 4 月 14 日
@Matthew Mishrikey thanks for your comment. I recall having this problem in the past but now when I test it with your code in MATLAB R2022a, I don't see the problem. The only change I made was to increase the axes size so I can more clearly see the ticks. I wonder what release of MATLAB you're using.
The tick label rotation became a feature after I added my answer but thanks for the reminder to update my answer to set rotation to 0.
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Axis Labels についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
アジア太平洋地域
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)