Axes labeling and over-plotting two graph having different data size

1 view (last 30 days)
I have a code which goes like this:
close;clear;clc
format long
TimeDuration=datetime(2012,10,12,16, 50,(00:0.0158:3600)');
BValue=linspace(60,150,227849)';
mp=1.6726*10^(-27);
e=1.602*10^(-19);
StartDate = datenum('12-Oct-2012 16:50:00');
EndDate = datenum('12-Oct-2012 17:50:00');
NoOfTickMarks=13;
xData = linspace(StartDate,EndDate,NoOfTickMarks);
%%
figure('units','normalized','outerposition',[0 0 1 1]) % Make figure full screen
subplot(2,1,1)
hammng_wndw_size=2^14;
window=hamming(hammng_wndw_size);
noverlap=512;
nfft=4096;
fs=64;
BForSpectring=sin(linspace(-pi,pi,227849)');
[Sp,F,T,P]=spectrogram(BForSpectring,window,noverlap,nfft,fs,'yaxis');
DateCnvrted2Serial=datenum(TimeDuration);
[Year,Month,Day,Hour,Minutes,Seconds]=datevec(TimeDuration);
TimeInDecimalFormat=Hour+Minutes/60+Seconds/3600;
Time4Spectrogrm=T./3600+TimeInDecimalFormat(1);
surf(Time4Spectrogrm,F,10*log10(P),'edgecolor','none','FaceColor','interp');
axis tight;
view(0,90);colormap(jet);
colorbar;
set(gca,'linewidth',1.5,'fontsize',12)
ax=gca;
% ax.XTickLabel=datestr(hours(ax.XTick),'HH:MM');
ylim([1 4]);
%%
subplot(2,1,2)
plot(TimeDuration,((e*BValue)/(4*mp*10^(9))),'LineWidth',1.5)
legend('A line')
set(gca,'linewidth',1.5,'fontsize',12)
ax=gca;
ax.XTick = xData;
datetick('x','HH:MM','keepticks')
whose output looks like this:
Now I have 3 questions:
  1. In the top panel, one can see that the tick marks are starting from 16:54. I thought that the code
ax.XTick = xData;
datetick('x','HH:MM','keepticks')
if I out below
set(gca,'linewidth',1.5,'fontsize',12)
ax=gca;
for subplot (2,1,1) will give the same x axis as shown for 2nd subplot. But it is not working. What am I doing wrong?
2. Now, I would spectrogram to occupy the same length as the 2nd subplot and put the colour bar outside as shown:
This can be done using plot tools manually. But is there a way to do it autonatically?
3. I would like to combine both the plot in a single figure, i.e. I would like to put the 2nd plot on to first. When I am putting hold on command on subplot(2,1,2), it doesn’t work. I realise that it is because the data points have different size. But is there a way to achieve it?
I am using matlab 2016a.
Thanks in advance...

Answers (1)

jonas
jonas on 20 Jul 2020
  1. Problem is that you're using the outdated date format. Most of your issues will probably go away if you change to datetime format (see below).
  2. I usually solve this by passing a location argument to colorbar(), which preserves the axes size if inside the axes. You can then change the colorbar position to the blank space outside of the axes (see below). You may also have to reduce the axes size or move them to the left.
  3. The problem is not about different size of data points but rather that you have different classes on the x-axis. You can use either decimal format (double) or datetime, not both.
close;clear;clc
format long
TimeDuration=datetime(2012,10,12,16, 50,(00:0.0158:3600)');
BValue=linspace(60,150,227849)';
mp=1.6726*10^(-27);
e=1.602*10^(-19);
StartDate = datetime('12-Oct-2012 16:50:00');
EndDate = datetime('12-Oct-2012 17:50:00');
NoOfTickMarks=13;
xData = linspace(StartDate,EndDate,NoOfTickMarks);
%%
figure('units','normalized','outerposition',[0 0 1 1]) % Make figure full screen
subplot(2,1,1)
hammng_wndw_size=2^14;
window=hamming(hammng_wndw_size);
noverlap=512;
nfft=4096;
fs=64;
BForSpectring=sin(linspace(-pi,pi,227849)');
[Sp,F,T,P]=spectrogram(BForSpectring,window,noverlap,nfft,fs,'yaxis');
DateCnvrted2Serial=datetime(TimeDuration);
[Year,Month,Day,Hour,Minutes,Seconds]=deal(year(TimeDuration),month(TimeDuration),...
day(TimeDuration),hour(TimeDuration),minute(TimeDuration),second(TimeDuration));
TimeInDecimalFormat=Hour+Minutes/60+Seconds/3600;
Time4Spectrogrm=T./3600+TimeInDecimalFormat(1);
surf(Time4Spectrogrm,F,10*log10(P),'edgecolor','none','FaceColor','interp');
axis tight;
view(0,90);colormap(jet);
cb = colorbar(gca,'east');
cb.Position = cb.Position + [0.05 0 0 0];
set(gca,'linewidth',1.5,'fontsize',12)
ax=gca;
% ax.XTickLabel=datestr(hours(ax.XTick),'HH:MM');
ylim([1 4]);
%%
subplot(2,1,2)
plot(TimeDuration,((e*BValue)/(4*mp*10^(9))),'LineWidth',1.5)
legend('A line')
set(gca,'linewidth',1.5,'fontsize',12)
ax=gca;
ax.XTick = xData;
ax.XAxis.TickLabelFormat = 'HH:mm';
  3 Comments
jonas
jonas on 20 Jul 2020
Edited: jonas on 20 Jul 2020
What is the error? I receive no error when I run the code in my answer. I do however receive an error at that line when I run your original code, which is because you try to add ticks defined as doubles to a datetime axis. You cannot mix datetime and datenum (class double, old date format), they are different classes.
plot(TimeDuration,((e*BValue)/(4*mp*10^(9))),'LineWidth',1.5)
% ↑ datetime
legend('A line')
set(gca,'linewidth',1.5,'fontsize',12)
ax=gca;
ax.XTick = xData;
% ↑ double
You can change from datetime to datenum (not recommended), by changing the first line above to
plot(DateCnvrted2Serial,((e*BValue)/(4*mp*10^(9))),'LineWidth',1.5)
...which would result in a plot similar to the one you posted, so I presume that is what you have already figured out.
When you change the format the ticks are preserved but the limits are changed, so you have to add another argument.
datetick('x','HH:MM','keepticks','keeplimits')
As for the 3rd problem, I really do not understand the issue. Your time arrays are completely different (one is a date, one is in "decimal hours"), so obviously they will not be overlapping.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!