Matlab plotting with Dates - matlab

The code below works fine as is, however I need to be able to change the start and end dates to be any given calendar date. So rather than run from 2002:2003 I would like to have it run from '15/Aug/2001' to '14/Aug/2002'. In addition I would like the y-axis to display these new dates.
The actual number of days between then will not be the same as calendar says but rather 255 days (in this case) I will have to enter the information manually.
It seems to be datetick can help but I cannot get it to fit into the framework below:
I know I've already asked a few questions on this piece of code but this will be the last one!
tchange=(1/(255-1));
x = 2002:tchange:2003; % x data
grad_ = rand(1,length(x))*.3; % graduated stuff
grad_2 = rand(1,length(x))*.3;
grad_3= rand(1,length(x))*.3;
h = subplot(1,3,1);
%plot(grad_,x); % flip x and y for vertical plot
herrorbar(grad_,x,grad_2,grad_3,'.');
axis(h, [0 0.5 2002 2003])
set(h, 'Ytick', x(1):x(end), 'Xtick', 0:.1:.5, 'YDir','reverse', 'YGrid', 'on');
xlabel('Gradient Search')
diff_ = rand(1,length(x)).^2 *.15; % differential stuff
h = subplot(1,3,2);
herrorbar(diff_,x,grad_2,grad_3,'.');
%plot(diff_,x);
set(h,'yticklabel',[], 'Ytick', x(1):x(end), 'Xtick', 0:.1:.5, 'YDir','reverse', 'YGrid', 'on');
axis(h, [0 0.5 2002 2003])
xlabel('Differential Evolution')
delta_ = rand(1,length(x)).^2 *.2 - .2; % delta stuff
h = subplot(1,3,3);
%plot(delta_,x);
stem(x,delta_median_LP(1:npoints,1),'Marker','.');
axis(h, [2002 2003 -.5 .5])
set(h,'Xtick', -.5:.5:.5, 'XGrid', 'on');
view(90,90);
ylabel('\Delta of medians')

You should be able to use MATLAB's datenum function, combined with the datetick function. For instance, for the first plot, you could do the following:
x = datenum(2001,8,15):datenum(2002,8,14); % x data
grad_ = rand(1,length(x))*.3; % graduated stuff
grad_2 = rand(1,length(x))*.3;
grad_3= rand(1,length(x))*.3;
h = subplot(1,3,1);
plot(grad_,x); % flip x and y for vertical plot
% herrorbar(grad_,x,grad_2,grad_3,'.');
axis(h, [0 0.5 x(1) x(end)])
set(h, 'Xtick', 0:.1:.5, 'YDir','reverse', 'YGrid', 'on');
datetick('y',24,'keeplimits');
xlabel('Gradient Search')
I remove the ytick part of the set command so that it uses the default, which isn't too bad in this case, but you could set it to whatever you wanted.

Related

MATLAB Subplot Make Figure Larger

I am plotting two maps next to each other using subplot. However, now, the image is turning out like this:
Is there any way to make the map part of the image larger? I would like to plot the maps side by side, by in this image, the resolution is low and the size is small.
%% Graph one site at a time
nFrames = 6240; % Number of frames.
for k = 94:nFrames
h11 = subplot(1,2,1); % PM2.5
% Map of conterminous US
ax = figure(1);
set(ax, 'visible', 'off', 'units','normalized','outerposition',[0 0 1 1]);
ax = usamap('conus');
set(ax,'Position',get(h11,'Position'));
delete(h11);
states = shaperead('usastatelo', 'UseGeoCoords', true,...
'Selector',...
{#(name) ~any(strcmp(name,{'Alaska','Hawaii'})), 'Name'});
faceColors = makesymbolspec('Polygon',...
{'INDEX', [1 numel(states)], 'FaceColor', 'none'}); % NOTE - colors are random
geoshow(ax, states, 'DisplayType', 'polygon', ...
'SymbolSpec', faceColors)
framem off; gridm off; mlabel off; plabel off
hold on
% Plot data
scatterm(ax,str2double(Lat_PM25{k})', str2double(Lon_PM25{k})', 25, str2double(data_PM25{k})', 'filled');
% Colorbar
caxis([5 30]);
h = colorbar;
ylabel(h,'ug/m3');
% Title
title(['PM2.5 24-hr Concentration ', datestr(cell2mat(date_PM25(k)), 'mmm dd yyyy')]);
%%%%
h22 = subplot(1,2,2); % O3
% Map of conterminous US
ax2 = usamap('conus');
set(ax2,'Position',get(h22,'Position'));
delete(h22);
states = shaperead('usastatelo', 'UseGeoCoords', true,...
'Selector',...
{#(name) ~any(strcmp(name,{'Alaska','Hawaii'})), 'Name'});
faceColors = makesymbolspec('Polygon',...
{'INDEX', [1 numel(states)], 'FaceColor', 'none'}); % NOTE - colors are random
geoshow(ax2, states, 'DisplayType', 'polygon', ...
'SymbolSpec', faceColors)
framem off; gridm off; mlabel off; plabel off
hold on
% Plot data
scatterm(ax2,str2double(Lat_O3{k})', str2double(Lon_O3{k})', 25, str2double(data_O3{k})'*1000, 'filled');
hold on
% Colorbar
caxis([10 90]);
h = colorbar;
ylabel(h,'ppb');
% Title
title(['O3 MDA8 Concentration ', datestr(cell2mat(date_O3(k)), 'mmm dd yyyy')]); % Title changes every daytitle(str);
% Capture the frame
mov(k) = getframe(gcf); % Makes figure window pop up
% Save as jpg
eval(['print -djpeg map_US_' datestr(cell2mat(date_PM25(k)),'yyyy_mm_dd') '_PM25_24hr_O3_MDA8.jpg']);
clf
end
close(gcf)
To change the amount of space the data occupies in the figure, you can use this command:
set(gca,'Position',[0.1 .1 0.75 0.85])
You'll have to play with the numbers a bit, to get things look nice. Note that Matlab rescales everything when you resize the figure window, so the optimal numbers depend on the window size you want to use.
On the other hand, you want to make the map bigger in comparison to the colorbar. You cannot make it without changing your window size, because your maps are already as high as the color bars. I would suggest to:
Set caxis to the same range in both plots.
Remove the colorbar on the left one.
Increase the height of your figure window to make the maps occupy as much width as possible.
Put the two images nicelye side by side using the command above.
For more information, see Matlab Documentation on Axes Properties.
Example:
% Default dimenstions
figure
x = 1:.1:4;
y = x;
[X, Y] = meshgrid(x,y);
subplot(1,2,1)
h = pcolor(X, Y, sin(X).*cos(Y)*2);
set(h, 'EdgeAlpha', 0);
axis square
colorbar
subplot(1,2,2)
h = pcolor(X, Y, sin(Y).*cos(X));
set(h, 'EdgeAlpha', 0);
axis square
colorbar
% adjust dimensions
subplot(1,2,1)
set(gca, 'Position', [0.1 0.1 0.3 0.85])
subplot(1,2,2)
set(gca, 'Position', [0.55 0.1 0.3 0.85])
This blog post has many great examples of FileExchange scripts dealing with size of subplots.
subplot_tight works very well and makes the subplots larger. Instead of writing in subplot(1,2,1), use subplot_tight(1,2,1)
My problem was similar -> scaling subplots in a figure a bit more up. Important for me though, was to maintain the aspect ratio that I've set before.
Enhancing the answer from #texnic in order to not have to set the values manually, one might use the following:
scale = 1.1; % Subplot scale
subplot(1,2,1)
% Your plotting here ...
pos = get(gca, 'Position'); % Get positions of the subplot [left bottom width height]
set(gca, 'Position', [pos(1) pos(2) pos(3)*scale pos(4)*scale]); % Scale width and height
Understanding this, one can also easily implement a parametric move of the subplot.

axes labels not displaying on 3d subplots

I have created 5 3D subplots which include a for loop. However, the labels of the X and Y axes are not displaying for some reason. I would appreciate any help on this matter. Below is the code.
On a separate note, any suggestions to make the figure more aesthetically pleasing would also be much appreciated.
% parameters
b=0.5;
O=27;
x=1:1:5;
% energies
e1 = 1:1:100;
e2 = 1:1:100;
% function
[e1,e2]=meshgrid(e1,e2);
hb=#(x)((O.^2)./factorial(O-x)).*...
exp(-b.*O.*e2);
hu=#(x)(O.^x).*...
exp(-b.*O.*e1);
p=#(x)hb(x)./(hb(x)+hu(x));
f=figure('visible','on')
clf(f);
for i=x
subplot(2,3,i);
mesh(e1,e2,p(i))
title(['X = ',int2str(i)], 'FontSize',12);
% log all axes
set(gca, 'XScale', 'log');
set(gca, 'YScale', 'log');
set(gca, 'ZScale', 'log');
axis([1 100 1 100 10^-300 1])
axis square
grid off
set(gca,'FontSize',10)
xlabel('e1')
ylabel('e2')
zlabel('p_{H}')
end
The issue seems to be something internal to MATLAB with how it is setting the position of the x and y labels when a 3D surface plot is used. This doesn't happen with a basic plot3 plot. If you do a get(get(gca,'Xlabel','Position')), you see that the z coordinate of the label is set to infinity, which I would guess is the problem.
I've come up with a less than ideal workaround, but it seems to accomplish the task:
% parameters
b=0.5;
O=27;
x=1:1:5;
% energies
e1 = 1:1:100;
e2 = 1:1:100;
% function
[e1,e2]=meshgrid(e1,e2);
hb=#(x)((O.^2)./factorial(O-x)).*...
exp(-b.*O.*e2);
hu=#(x)(O.^x).*...
exp(-b.*O.*e1);
p=#(x)hb(x)./(hb(x)+hu(x));
f=figure('visible','on');
clf(f);
for i=x
subplot(2,3,i);
mesh(e1,e2,p(i))
title(['X = ',int2str(i)], 'FontSize',12);
% log all axes
set(gca, 'XScale', 'log');
set(gca, 'YScale', 'log');
set(gca, 'ZScale', 'log');
axis([1 100 1 100 10^-300 1])
axis square
grid off
set(gca,'FontSize',10)
xlabel('e1')
ylabel('e2')
zlabel('p_{H}')
set(get(gca,'xlabel'),'Units','Normalized','Position',[0.75 0 0])
set(get(gca,'ylabel'),'Units','Normalized','Position',[0 0.05 0])
end
You'll probably have to manipulate those position vectors to get the labels exactly where you'd like.
I would also submit a bug report and see what MathWorks says.

Zoom region within a plot in Matlab

I'm using Matlab to produce figures, and I'm wondering if there is a way to plot a zoomed region in a figure of the overall data?
I have scatter data plotted over one week, with the x-axis in hours, and I want to zoom into the first 3 hours, and display them within the main figure with the x-axis label of minutes.
The plotting code I have so far is as follows:
allvalsx = marabint(:,2)
allvalsy = marabint(:,5)
subvalsx = marabint(1:7,2);
subvalsy = marabint(1:7,2);
%% Plots the scatter chart.
sizemarker = 135
handle = scatter(allvalsx, allvalsy, sizemarker, '.')
figure(1)
axes('Position',[.2 .2 .2 .2])
handle2 = scatter(subvalsx, subvalsy, '.r')
title(plotTitle)
xlabel('Time since treatment (hours)')
ylabel('Contact angle (deg)')
% Axis scales x1, x2, y1, y2
axis([0, marabint(length(marabint),2) + 10, 0, 120]);
% This adds a red horizontal line indicating the untreated angle of the
% sample.
untreatedLine = line('XData', [0 marabint(length(marabint),2) + 10], 'YData', [untreatedAngle untreatedAngle], 'LineStyle', '-', ...
'LineWidth', 1, 'Color','r');
% Adding a legend to the graph
legendInfo = horzcat('Untreated angle of ', untreatedString)
hleg1 = legend(untreatedLine, legendInfo);
% This encases the plot in a box
a = gca;
% set box property to off and remove background color
set(a,'box','off','color','none')
% create new, empty axes with box but without ticks
b = axes('Position',get(a,'Position'),'box','on','xtick',[],'ytick',[]);
% set original axes as active
axes(a)
% link axes in case of zooming
linkaxes([a b])
set(gcf,'PaperUnits','inches');
set(gcf,'PaperSize', [8.267 5.25]);
set(gcf,'PaperPosition',[0 0.2625 8.267 4.75]);
set(gcf,'PaperPositionMode','Manual');
set(handle,'Marker','.');
print(gcf, '-dpdf', '-r150', horzcat('markertest4.pdf'));
This produces the following
Can anyone help me out with this?
yeah, I think I know what you need. Try this:
zoomStart = 0;
zoomStop = 3;
set(gca, 'XLim', [zoomStart zoomStop])
Let me know if that doesn't do what you need, and I'll give you a different way.

MATLAB Figure Visible Off

I'm trying to save .jpg files from MATLAB, but I don't want to have the figure pop up every time since this really slows down the process. However, setting 'visible' to 'off' doesn't seem to work. What can I do to get the Figure window to not pop up?
nFrames = 2557; % Number of frames. Number of days between 1/1/2008 and 1/31/2014
for k = 183:nFrames % 183 (7/1/2008) to the number of days. Data before this is either missing or from HI
% Map of conterminous US
ax = figure(1);
set(ax, 'visible', 'off', 'units','normalized','outerposition',[0 0 1 1]) % Make window that shows up full sized, which makes saved figure clearer
ax = usamap('conus');
states = shaperead('usastatelo', 'UseGeoCoords', true,...
'Selector',...
{#(name) ~any(strcmp(name,{'Alaska','Hawaii'})), 'Name'});
faceColors = makesymbolspec('Polygon',...
{'INDEX', [1 numel(states)], 'FaceColor', 'none'}); % NOTE - colors are random
geoshow(ax, states, 'DisplayType', 'polygon', ...
'SymbolSpec', faceColors)
framem off; gridm off; mlabel off; plabel off
hold on
% Plot data
scatterm(ax,str2double(Lat_PM25{k}), str2double(Lon_PM25{k}), 40, str2double(data_PM25{k}), 'filled'); % Plot a dot at each Lat and Lon with black outline around each dot (helps show dots that are too low for it to be colored by the color bar
% Draw outline around dot with 'MarkerEdgeColor', [0.5 0.5 0.5] for gray
hold on
% Colorbar
caxis([5 30]);
h = colorbar;
ylabel(h,'ug/m3');
% Title
% date = datenum(2007, 04, 29) + k; % Convert t into serial numbers.
title(['PM2.5 24-hr Block Average Concentration ', datestr(cell2mat(date_PM25(k)), 'mmm dd yyyy')]); % Title changes every day;
% Capture the frame
mov(k) = getframe(gcf);
% Set size of paper
set(gcf,'Units','points')
set(gcf,'PaperUnits','points')
size = get(gcf,'Position');
size = size(3:4);
set(gcf,'PaperSize',size)
set(gcf,'PaperPosition',[0,0,size(1),size(2)])
% Save as jpg (just specify other format as necessary) - Must set 'facecolor' to 'none' or else color of states turn out black
eval(['print -djpeg map_US_' datestr(cell2mat(date_PM25(k)),'yyyy_mm_dd') '_PM25_24hrBlkAvg.jpg']);
clf
end
The problem is with getframe. A detailed answer was given in this thread and in this discussion.
In short you need to avoid getframe and instead do something like the following:
ax = figure(1);
set(ax, 'visible', 'off')
set(ax, 'PaperPositionMode','auto')
aviobj = avifile('file.avi');
....
for k=1:N
%# all the plotting you did before the getframe
img = hardcopy(ax, '-dzbuffer', '-r0');
aviobj = addframe(aviobj, im2frame(img));
end
aviobj = close(aviobj);

Plot outside axis in Matlab

How to plot something outside the axis with MATLAB? I had like to plot something similar to this figure;
Thank you.
Here is one possible trick by using two axes:
%# plot data as usual
x = randn(1000,1);
[count bin] = hist(x,50);
figure, bar(bin,count,'hist')
hAx1 = gca;
%# create a second axis as copy of first (without its content),
%# reduce its size, and set limits accordingly
hAx2 = copyobj(hAx1,gcf);
set(hAx2, 'Position',get(hAx1,'Position').*[1 1 1 0.9], ...
'XLimMode','manual', 'YLimMode','manual', ...
'YLim',get(hAx1,'YLim').*[1 0.9])
delete(get(hAx2,'Children'))
%# hide first axis, and adjust Z-order
axis(hAx1,'off')
uistack(hAx1,'top')
%# add title and labels
title(hAx2,'Title')
xlabel(hAx2, 'Frequency'), ylabel(hAx2, 'Mag')
and here is the plot before and after:
You can display one axis with the scale you want, then plot your data on another axis which is invisible and large enough to hold the data you need:
f = figure;
% some fake data
x = 0:20;
y = 23-x;
a_max = 20;
b_max = 23;
a_height = .7;
%% axes you'll see
a = axes('Position', [.1 .1 .8 a_height]);
xlim([0 20]);
ylim([0 20]);
%% axes you'll use
scale = b_max/a_max;
a2 = axes('Position', [.1 .1 .8 scale*a_height]);
p = plot(x, y);
xlim([0 20]);
ylim([0 b_max]);
set(a2, 'Color', 'none', 'Visible', 'off');
I had similar problem and I've solved it thanks to this answer. In case of bar series the code is as follows:
[a,b] = hist(randn(1000,1)); % generate random data and histogram
h = bar(b,a); % plot bar series
ylim([0 70]) % set limits
set(get(h,'children'),'clipping','off')% turn off clippings