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.
Related
I run into the problem where Matlab 2015b expands the labels of new Xticks when the x-axis gets bigger by using incomplete label, zeros, in the thread No Gap Next to Axis Label in Matlab?
The dynamic expansion of incomplete labels of xticks is not possible because there is always cases of insufficient space but only one symbol is needed to mark half between two values.
The situation is problematic with zeros because I have several calibration points and several systems where the extra zeros are errorprone.
I would like to have there another symbol.
Example code how to create those incomplete labels of xticks
labels = arrayfun(#(x)sprintf('%.2g', x), xticks, 'uniform', 0);
ax2 = axes('OuterPosition', [0.51 0.5 0.5 0.5]); % anything here
xticks = get(ax2, 'xtick'); % https://stackoverflow.com/a/35776785/54964
set(ax2, 'xticklabels', labels); % here the point!
Without those incomplete labels of xticks but broader labelling which is worser
labels = arrayfun(#(x)sprintf('%.2g', x), xticks, 'uniform', 0);
ax2 = axes('OuterPosition', [0.51 0.5 0.5 0.5]);
xticks = get(ax2, 'xtick'); % https://stackoverflow.com/a/35776785/54964
set(ax2, 'xtick', xticks, 'xticklabels', labels);
Output of Suever's answer
Beautiful Small window in the original size with scientific numbering because of callback(); at the end of the code following
Medium window
Code
hFig=figure;
data=randi(513,513);
D=mat2gray(pdist(data, 'correlation'));
ax2 = axes('OuterPosition', [0.51 0.5 0.5 0.5]);
plot(D, 'Parent', ax2);
axis(ax2, 'square');
title('Corr pdist');
cbar2 = colorbar();
set(ax2, 'XLim', [0 size(D,2)]);
set(cbar2, 'Visible', 'off')
grid minor;
labelconverter = #(x)sprintf('%.2g', x); % https://stackoverflow.com/a/35780915/54964
callback = #(varargin)set(ax2, 'xticklabels', arrayfun(labelconverter, get(ax2, 'xtick'), 'uniform', 0));
set(hFig, 'SizeChangedFcn', callback);
callback(); % necessary for small window
How can you have another symbol for the incomplete labels of xticks in Matlab?
As I said in the other question, if you want the labels to be updated automatically when you resize things, you'll want to do the following.
fig = figure;
% Set large xlimits to demonstrate the issue at hand
ax2 = axes('xlim', [0 1e9]);
% Force a draw event to have the axes determine where the
labelconverter = #(x)sprintf('%.2g', x);
callback = #(varargin)set(ax2, 'xticklabels', arrayfun(labelconverter, get(ax2, 'xtick'), 'uniform', 0));
set(fig, 'SizeChangedFcn', callback);
% Be sure to execute the callback to get new labels prior to figure resize.
callback();
As you change the size of your figure, the labels will be changed automatically and the positions will be updated.
Small Window
Medium Window
Large Window
Note: Test this code in isolation to verify that it works, then adapt the idea to your solution. It seems like you're ending up with a lot of complications because your namespace is polluted (for example your examples don't even run because labels isn't defined).
Matlab 2015b or Matlab 2016a.
I would like to have grid lines going across Subplot's spacing between the figures in order to evaluate better two pictures horizontally.
However, I have a small gap between the two figures at the lower right-hand-side corner because which is misaligning the figures
where the gap is because of the 10^4 at lower right-hand-side corner.
I would also like to have horizontal lines going across the spacing between the two figures, but I cannot do it before the gap problem is solved.
Code where the relative alignment is done as described in the answer here about the thread Tight subplot with colorbars and subplot's 3rd parameter in Matlab?
data=randi(513,513);
D=mat2gray(pdist(data, 'correlation'));
% Set normalized outer position (x,y,width,height)
ax1=axes('OuterPosition', [0 0.5 0.5 0.5]);
plot(D, 'Parent', ax1);
xlim([0 size(D,2)]);
set(cbar1, 'Visible', 'off')
title('Signal');
ax2=axes('OuterPosition', [0.51 0.5 0.5 0.5]);
plot(D, 'Parent', ax2);
set(ax2, 'XLim', [0, size(D,1)])
axis(ax2, 'square');
title('Corr pdist');
Output of Suever's answer
I tried unsuccessfully change two (2) in sprintf('%.2g', x) bigger and smaller
ax2 = axes('OuterPosition', [0.51 0.5 0.5 0.5]);
plot(D, 'Parent', ax2);
set(ax2, 'XLim', [0, size(D,1)])
axis(ax2, 'square');
title('Corr pdist');
cbar2 = colorbar(); % ax2 not needed here in brackets
set(ax2, 'XLim', [0 size(D,2)]);
set(cbar2, 'Visible', 'off')
grid minor;
% https://stackoverflow.com/a/35776785/54964
xticks = get(ax2, 'xtick');
labels = arrayfun(#(x)sprintf('%.2g', x), xticks, 'uniform', 0);
set(ax2, 'xticklabels', labels);
It gives
where those ticks are not XMinorTicks but simply ticks (wrongly marked in the picture).
They are zero points at some points in the x-axis. When x-axis gets larger, MATLAB automatically adds new xtick marks but without complete labels.
I think it would be better to have another symbol than zero there. How can you have some other mark than zero for incomplete labels of xticks?
How can you align the 10^4 next to the last number in the second figure?
I would get the current xtick locations, convert those to strings, and then set the xticklabels property of the axes.
xticks = get(ax2, 'xtick');
labels = arrayfun(#(x)sprintf('%.2g', x), xticks, 'uniform', 0);
set(ax2, 'xtick', xticks, 'xticklabels', labels);
If you want them to dynamically be computed as the figure changes size (and the xticks get recomputed) you can link this code to the SizeChangedFcn of the figure.
func = #(varargin)set(ax2,'xticklabels',arrayfun(#(x)sprintf('%.2g',x),get(ax2, 'xtick'),'uni',0));
set(gcf, 'SizeChangedFcn', func)
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.
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);
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