Multiple labels on xaxis

46 views (last 30 days)
Sreeraj T
Sreeraj T on 16 May 2021
Edited: dpb on 19 May 2021
I have a code which goes like this:
clear;clc
close all;
EventDuation=datetime(2012,10,12,16,50,(linspace(0,265,605))');
AValue=log10(linspace(12.858000,690.02002,605)');
BValue=exp(linspace(2.3,3.215,605)');
CValue=log(linspace(2.3,3.215,605)');
figure()
subplot(311)
plot(BValue,AValue);axis tight
xAxisDataBValue=linspace(BValue(1),BValue(end),10);
ax=gca;
ax.XTick=xAxisDataBValue;
ax.TickDir = 'both';% Tick mark direction.
xlabel('B Value');ylabel('AValue')
subplot(312)
plot(CValue,AValue);axis tight
xAxisDataCValue=linspace(CValue(1),CValue(end),10);
ax=gca;
ax.XTick=xAxisDataCValue;
ax.TickDir = 'both';% Tick mark direction.
xlabel('C Value');ylabel('AValue')
subplot(313)
plot(EventDuation,AValue);axis tight
xAxisDataEventDuration=linspace(EventDuation(1),EventDuation(end),10);
ax=gca;
ax.XTick=xAxisDataEventDuration;
datetick('x','HH:MM:SS','keepticks')
ax.TickDir = 'both';% Tick mark direction.
xlabel('Time');ylabel('AValue')
giving a plot like this:
As the y axis is the same I would like to combine the x axis together and produce a plot like this:
I took clue from here and added this:
yMin=min(ylim);
yRange= diff(ylim);
xTickValues=get(gca, 'XTick');
nrxt=size(xTickValues,2);
latvct=xAxisDataEventDuration;
lat_txt=cellstr(strsplit(num2str(datenum(latvct),'%.2f '),' '));
text([(xTickValues(1)-xTickValues(2))*0.5 xTickValues],...
ones(1,nrxt+1)*yMin-0.1*yRange, ['Lat ' lat_txt],'HorizontalAlignment','center')
but since I am having one of the axes in datetime format, I am having a trouble in getting the plot. Further, I did not understand some line in the code there, especially what does the things in ‘text([(xt(1)-xt(2))*0.5 xt], ones(1,nrxt+1)*ymin-0.05*yrng, ['Lat ' lat_txt],'HorizontalAlignment','center')’ and other similar line does.
I spent a great deal of time, but could not produce the plot. Any help will be deeply appreciated.
I am using MATLAB2020b

Answers (1)

dpb
dpb on 16 May 2021
Edited: dpb on 18 May 2021
That's one way; I'd just rearrange the sizes/locations (position property) of the subplots to collapse the bottom two down so nothing but the axes shows and then move the third to fill the space. It's not bad and can be coded to be generic -- I'll just illustrate with the ad hoc adjustments I did to illustrate --
% begin with your code outline
% rearrange to use cell arrays so can write generic loop...
A=log10(linspace(12.858000,690.02002,605)');
BCD=[{exp(linspace(2.3,3.215,605)')} ...
{log(linspace(2.3,3.215,605)')} ...
{datetime(2012,10,12,16,50,(linspace(0,265,605))')}];
for i=1:3
hAx(i)=subplot(3,1,i);
hL(i)=plot(BCD{i},A);
axis tight
hAx(i).XTick=linspace(BCD{i}(1),BCD{i}(end),10);
hAx(i).TickDir = 'both';
end
hAx(3).XAxis.TickLabelFormat='HH:mm:ss'; % fixup format string for datetime axes
hAx(3).XAxis.SecondaryLabel.String=''; % get rid of the date label
P=reshape(hAx.Position,4,[]).'; % get the position vectors as array for each
hAx(3).Position=[P(3,1:3) 0.001]; % collapse bottom axes to only show axes
hAx(2).Position=[P(2,1) P(3,2)+P(3,4)+0.075 P(2,3) 0.001];
hAx(1).Position=[P(1,1) P(3,2)+2*[0.001+0.075] P(1,3) P(1,2)+P(1,4)-0.3]; % now move, resize first
xlabel(hAx(3),'Time') % put time on the bottom axis
hTxt(1)=annotation('textbox',[0 0.18 0.1 0.1],'string','C','HorizontalAlignment','right','fitboxtotext','on','LineStyle','none');
hTxt(2)=annotation('textbox',[0 0.10 0.1 0.1],'string','B','HorizontalAlignment','right','fitboxtotext','on','LineStyle','none');
Above leaves with--
  5 Comments
Sreeraj T
Sreeraj T on 18 May 2021
@dpb , once again I really appreciate your effort. Now I understand why that error was coming. However, now I am facing another error.
Error using datetime/linspace (line 14)
Comparison is not defined between double and datetime arrays.
Error in Untitled (line 41)
hAx(i).XTick=linspace(BCD{i,1},BCD{i,end},10);
There may be two problems:
  1. When the loop is running, i first take the value 1 which means it is BCD{1,1} and BCD{1,end}. This will give a double array and datetime array, respectively. If my understanding is correct, then input arguments for linspace is pair of numeric scalars, not an array: linspace(BCD{i,1}(1,1),BCD{i,2}(1,1),10) gives correct answer, but linspace(BCD{i,1},BCD{i,2},10) will give error ‘Inputs must be scalars.’ Further, we cannot have linspace(BCD{i,1}(1,1),BCD{i,end}(1,1),10), as the "Comparison is not defined between double and datetime arrays." As i advances, it will give another error which is explained below.
  2. When i becomes 2, BCD{2,1} we will get an error ‘Index in position 1 exceeds array bounds (must not exceed 1)’. Did you meant to write BCD{1,i}, so that as i advances, it becomes BCD{1,2} and then BCD{1,3} ?
So, if I change the program incorporating the suggestions to this:
for i=1:3
hAx(i)=subplot(3,1,i);
hL(i)=plot(BCD{:,i},A);
axis tight
hAx(i).XTick=linspace(BCD{1,i}(1,1),BCD{end,i}(end,1),10);
hAx(i).TickDir = 'both';
end
I will get the same plot from where I started, but the problem remains open.
Once again, many thanks for your effort. I am not sure whether I could articulate my problem well, even though this comment is pretty big :) .
dpb
dpb on 18 May 2021
Edited: dpb on 19 May 2021
I said it was still "air code!" :)
I had other things I had to go do...I did get a little careless with the cell array indexing -- linspace does work ok with datetime as inputs, at least with the releases I've got installed; I don't know how far back that goes. At the moment I only have R2020b active so can't go back altho I think that goes back quite a ways...
To get the values you want for the xtick, it's
hAx(i).XTick=linspace(BCD{i}(1),BCD{i}(end),10);
since linspace requires an input for x1,x2,n all three for anything but the default 100 points.
If linspace could accept a vector for [x1,x2], you could write the dereferencing expression a little more succinctly as
hAx(i).XTick=linspace(BCD{i}([1 end]),10);
that would return the vector. But, that doesn't help for the actual need here; is just a sidelight on more generic indexing expressions.
BCD{i} dereferences the full vector; then you use regular () to address the elements of the vector. I just automatically wrote the curlies around both subscripts instead in a hurry as I still had the idea of a 2D array in the back of mind instead of a cell array each cell of which is a vector...so the other dereferencing expression is more succinctly (and understandable) as
BCD{i}
since each cell is a vector, the colon operator is not needed--that would be to reference the ith column in a 2D array. While it works for the cell array, it's superfluous and makes for harder reading of the code than the above.
I've made those corrections in the Answer code as well...
I'm not sure what problem remains open???
The remainder of the code after the initial subplots are created rearranges them to produce the final figure shown.
One could start and make the bottom axes independently; you really don't need to plot the data for them, anyways.

Sign in to comment.

Tags

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!