MATLAB Plotting dot in a specific area over a contourfm plot - matlab

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

Related

Using roof of a graph as x-axis for another

I've plotted a graph using pcolor which gives me the following graph-
My aim is to use the roof of the graph (by roof) I mean the highest axis (in this case, the line which is defined by y=57) as the base for a further graph.
I was able to use hold on to generate the following-
Code for this (removed some parts that defined the axis labels etc for brevity)-
load sparsemap ;
load d ;
residues = 57 ;
z = zeros(residues,residues); % define the matrix
index = find(sparsemap(:,3) ~= 0) ;
values = length(index);
hold on
%Plots the map you see in the first photo-
for k = 1:values
z(sparsemap(index(k),1),sparsemap(index(k),2)) = sparsemap(index(k),3);
z(sparsemap(index(k),2),sparsemap(index(k),1)) = sparsemap(index(k),3);
end
%Plots the line plot at the bottom of the graph.
A = d(:,1);
B = d(:,2) ;
plot(A, B) ;
pcolor(1:residues,1:residues,z);
works = load('colormap_works');
colormap(works);
colorbar;
As you can see, the line plot is using the same x axis as the first graph.
I am trying to get the line plot to come on top of the figure. I imagine a final figure like so-
Any ideas as to how I can use the top part of the first graph?
You can use 2 subplots. Here is an example:
data = randi(50,20,20); % some data for the pcolor
y = mean(data); % some data for the top plot
subplot(5,1,2:5) % create a subplot on the lower 4/5 part for the figure
pcolor(data) % plot the data
colormap hot;
h = colorbar('east'); % place the colorbar on the right
h.Position(1) = 0.94; % 'push' the colorbar a little more to the right
ax = gca;
pax = ax.Position; % get the position for further thightning of the axes
ax.YTick(end) = []; % delete the highest y-axis tick so it won't interfere
% with the first tick of the top plot
subplot(5,1,1) % create a subplot on the upper 1/5 part for the figure
plot(1:20,y) % plot the top data
ylim([0 max(y)]) % compact the y-axis a little
ax = gca;
ax.XAxis.Visible = 'off'; % delete the x-axis from the top plot
ax.Position(2) = pax(2)+pax(4); % remove the space between the subplots
Which creates this:

Multiple axes for a single surf plot

I have a surf plot, in which I would like to have two y-axes. I cannot seem to find any other discussion quite like this.
The closest I got so far is:
surf(peaks);
view(0,0)
ax(1) = gca;
axPos = ax(1).Position;
ax(2) = axes('Position',axPos, 'Color', 'none','XTick',[],'ZTick',[],'YAxisLocation','right');
linkprop(ax, 'CameraPosition');
rotate3d on
% Desired plot
surf(peaks);
% Save axis
ax(1) = gca;
% Use the position of the first axis to define the new axis
pos = ax(1).Position;
pos2 = pos - [0.08 0 0 0];
ax(2) = axes('Position',pos2,'Color', 'none');
% Plot random line in 3D, just make sure your desired axis is correct
plot3(ones(length(peaks),1), 10:10:length(peaks)*10,...
ones(length(peaks),1), 'Color','none')
% Make plot, and non-desired axes, invisible
set(gca,'zcolor','none','xcolor','none','Color','none')
% Link axes
linkprop(ax, 'View');

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