MATLAB Figure Visible Off - matlab

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);

Related

matlab plot with multiple colormaps

I want to create a plot with pcolor plot with an contour plot on top. Both with different colormaps - pcolor with "hot", the contour with "gray".
I newer Matlab version multiple colormaps are possible.
The code works, however both axis do not overlap, even if the axes positions are in sync.
%% prepare Data
Data2D = peaks(100);
Data2D = Data2D -min(Data2D(:));
Data2D = Data2D/max(Data2D(:)) * 100;
steps = 0:05:100;
xAxis = 1:size(Data2D,2);
yAxis = 1:size(Data2D,1);
figure(1); clf
ax1 = axes;
hold on;
% 3D flat plot
caxis([0 100]);
cmap = fliplr(jet(1000));
colormap(ax1, cmap(1:800,:));
hplot = pcolor(ax1, xAxis, yAxis, Data2D);
shading flat; % do not interpolate pixels
set(ax1,'XLim',[xAxis(1) xAxis(end)]);
set(ax1,'YLim',[yAxis(1) yAxis(end)]);
% colorbar
hcb = colorbar('location','EastOutside');
set(hcb, 'Ylim', [0 100]);
%% contour plot
ax2 = axes; linkaxes([ax1,ax2])
colormap(ax2, flipud(gray(1000)));
[C,hfigc] = contour(ax2, xAxis, yAxis, Data2D,steps);
% Hide the top axes
ax2.Visible = 'off';
ax2.XTick = [];
ax2.YTick = [];
set(hfigc, 'LineWidth',1.0);
hold off;
drawnow
If you didn't use ax2.Visible = 'off' you would probably see that the axes' positions are different, since the first axes are squashed to allow room for the colorbar which the second axes don't have.
TL;DR
You need to set the position properties to be equal
ax2.Position = ax1.Position
Demo
You can simulate this with a blank figure:
1.
% Create figure and first axes, which have a colorbar
figure(1)
ax1 = axes();
colorbar('location', 'eastoutside');
Output:
2.
% Add new axes
hold on;
ax2 = axes();
Output (notice the second axes fills the space of the first + colorbar):
3.
% Make the same, so that the second axes also allow for the colorbar
ax2.Position = ax1.Position;
Output (notice thicker numbers showing they are overlapping fully):

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.

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 Plotting dot in a specific area over a contourfm plot

I have a contourfm plot on which I want to place a dot. The contourfm plot by itself works fine with no error. But when I try to place a dot at a specific point, it overrides the contourfm plot and just places a dot on a white background without the eqdconic figure and with the latitude and longitude lines squashed together. I am using hold on and I've tried plotting the data first and plotting the dot first, but both produce the same result. Can anyone tell me what I'm doing wrong? I think maybe I should not be using 'plot' as the command.
** The code has been modified to reflect the answer. plotm was used instead of plot. the x and y values for the dot was switched to reflect MATLAB's lat, lon order (instead of lon, lat.)
% Eqdconic script
% Define figure and axes
fg1 = figure(1);
% set(fg1, 'paperposition', [0 0 8.5 8.5]);
axesm('MapProjection','eqdconic', 'MapParallels', [], 'MapLatLimit',[-80 -60],'MapLonLimit',[190 250]) % 60-70S and 120-160W
framem on; gridm on; mlabel on; plabel on; hold all;
% Old code that was incorrect:
% xValue = find(x(:,1) == 224); % Longitude closest to 136 03.56W
% yValue = find(y(1,:) == -66.75); % Latitude closest to 66 39.67S
% plot(xValue,yValue,'b.','MarkerSize',20); % Plot a black dot
% Plot dot
plotm(-66.75,224,'k.','MarkerSize',20);
hold on
% Plot data
frame = dataPoint(:,:,k);
contourfm(y,x,frame, 'LineStyle', 'none');
% Colorbar
caxis([0 100]);
h = colorbar;
ylabel(h,'Percent');
% Title: Days 1:1258 inclusive. 20100101 to 20130611
date = datenum(2009, 12, 31) + k; % Convert t into serial numbers
str = datestr(date, 'mmm yyyy');
title(str);
1
Use plotm instead of plot.
2
Replace this line
plot(xValue,yValue,'b.','MarkerSize',20); % Plot a black dot
with
plotm(x(xValue,1),y(1,yValue),'b.','MarkerSize',20); % Plot a black dot
Note that find returns the index of the found element not its value. However, in your case you can actually pass the actual values
3
If you will not use xValue and yValue later you can remove these lines
xValue = find(x(:,1) == 224); % Longitude closest to 136 03.56W
yValue = find(y(1,:) == -66.75); % Latitude closest to 66 39.67S
and change the plotting line to
plotm(224,-66.75,'b.','MarkerSize',20); % Plot a black dot
4
However this will not plot the dot because the latitude and longitude are swapped comparing to the ranges you have mentioned in axesm command. But since you use contourfm(y,x), I assume there should be swapped so the plotting line will be
plotm(-66.75,224,'b.','MarkerSize',20); % Plot a black dot
5
which gives us a blue dot, so we change the color to black by using 'k.' instead of 'b.' and we have
% Eqdconic script
% Define figure and axes
fg1 = figure(1);
% set(fg1, 'paperposition', [0 0 8.5 8.5]);
axesm('MapProjection','eqdconic', 'MapParallels', [], 'MapLatLimit',[-80 -60],'MapLonLimit',[190 250]) % 60-70S and 120-160W
framem on; gridm on; mlabel on; plabel on; hold all;
plotm(-66.75,224,'k.','MarkerSize',20); % Plot a black dot
which produces

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