How get position of mouse in my setting axis in matlab? - matlab

I have problem with my matlab project.
(my init block)
hFig = figure('Name', 'Form', 'NumberTitle', 'off');
set(hFig, 'PaperUnits', 'points')
axis([0 10 0 10]);
axis square off
when I call this function
MouseCoord = get(src, 'CurrentPoint');
I get mouse's position isn't in my coordinate (different scale axis, I think in picsels)
How get position of mouse in my setting axis [0 10 0 10] ?

Try using a handle to the axis directly:
src = get(hFig,'Children');
MouseCoord = get(src, 'CurrentPoint');
MouseCoord = MouseCoord(1,1:2);
The reason to do with the last line has to do with the different definition of CurrentPoint between figure and axis. Presuming you're only looking at 2D data, you don't need the full output.

Related

MATLAB: update surface plot and change location of line objects in while loop

So I am encountering a couple errors and am not sure where they're coming from. I won't post the whole code, but I will do my best to explain (fear I will be accused of plagiarism).
The assignment is to create a window with two plots: a surface plot and a contour plot. The surface plot represents elevation of a portion of the map represented by the contour plot. The portion is indicated by a blue box on the contour plot. I've successfully plotted the surface and contour plots and have identified the first area with a blue box. However, now I need to implement a menu system wherein the user enters 1, 2, 3, or 4 to move the box north, south, east or west.
Here is how I instantiated the plots:
fig = figure(1);
[xGrid, yGrid] = meshgrid(xMeters(xStart:xEnd), yMeters(yStart:yEnd));
%surface plot
elevationBox = ELEV(xStart:xEnd, yStart:yEnd);
surface = subplot(2, 1, 1);
surf(xGrid, yGrid, elevationBox);
axis([0 max(xGrid(:)) 0 max(yGrid(:)) min(elevationBox(:)) max(elevationBox(:))]);
axis tight;
%contour plot
elevation = ELEV;
[xMap, yMap] = meshgrid(xMeters(1:335), yMeters(1:230));
map = subplot(2, 1, 2); contour(xMap, yMap, elevation);
axis([0 max(xMeters(:)) 0 max(yMeters(:))]);
axis fill;
set(fig, 'Position', [500 100 600 700]);
right = line(xRight, xLeft);
left = line(xLeft, yLeft);
top = line(xTop, yTop);
bottom = line(xBottom, yBottom);
So all that works fine. Obviously I didn't include the parts where I defined the data and everything. After this comes a switch statement that changes the values of xLeft, yLeft, etc as well as xStart, xEnd etc.
Here is my attempt to update the plots:
[xGrid, yGrid] = meshgrid(xMeters(xStart:xEnd), yMeters(yStart:yEnd));
elevationBox = ELEV(xStart:xEnd, yStart:yEnd);
subplot(2, 1, 1)
set(surface, 'XData', xGrid, 'YData', yGrid, 'ZData', elevationBox);
drawnow;
I can choose an option and there is no error, but the plot doesn't update and when I quit the program I get this error:
Error using matlab.graphics.axis.Axes/set
There is no XData property on the Axes class.
Error in A9 (line 129)
set(surface, 'XData', xGrid);
The setting is inside the while loop but outside the switch statement. I also had a few lines using set on the line objects but those weren't working either so I thought I'd focus here first. I'm figuring whatever I'm doing wrong applies to both object types but if not let me know.
Thanks!
Rather than grab a handle to the axis (which you call surface), you want the data object. So grab a handle at surf_h = surf(...);.
A little example:
% Generate a random surface grid
n = 10;
[x, y] = meshgrid(1:n, 1:n);
z = rand(n);
% Plot
fig_h = figure(1);
axis_h = subplot(2, 1, 1);
surf_h = surf(x,y,z);
% Modify XData
set(surf_h, 'XData', -x);
drawnow;

Matlab: geoshow's grid and frame

I'm currently trying to plot a map from a .shp file and the result is not aesthetically pleasing:
minx=-75;
maxx=-68;
miny=-40;
maxy=-30;
cntry02=shaperead('cntry02', 'UseGeoCoords', true);
figure
geoshow(cntry02, 'FaceColor', [1 1 1]);
axis([minx-1 maxx+1 miny-1 maxy+1])
grid on
which produces
Is there a way to
1) plot all the grid (over the countries)?
2) plot the entire frame?
3) display S and W, instead of negative values of latitude and longitude?
I've been fighting with this problem all the morning. Thanks in advance.
You can download the .shp file from here.
http://openmap.bbn.com/svn/openmap/trunk/share/data/shape/cntry02/
For problem 1 and2, the reason is that the axes are always behind the plot. So one solution is to add new axes on the current one and display grid, box, and customized ticks.
For problem 3, I use regexprep to replace negative latitude with S suffix (idem for longitude). The only problem I have is that longitude 0 will be 0E, and latitude 0, 0N.
And here is the code:
figure;
axes;
geoshow(cntry02, 'FaceColor', [1 1 1]);
axis([minx-1 maxx+1 miny-1 maxy+1]);
axis off;
hold on; %hold to add new axes
axes('Color','none'); %specify no background, else default is here white
axis([minx-1 maxx+1 miny-1 maxy+1]);
grid on;
box on;
set(gca,'XTick', minx-1:2:maxx+1);
%compute x tick labels
xticks = num2str(minx-1:2:maxx+1);
xticks = regexprep(regexprep(xticks,'-([\d.]+)','$1W'), '\b[\d\.]+','$0E');
xticks_cell = cellstr(regexp(xticks,'\s+','split'));
set(gca,'XTickLabel',xticks_cell)
set(gca,'YTick', miny-1:2:maxy+1);
% compute y tick labels
yticks = num2str(miny-1:2:maxy+1);
yticks = regexprep(regexprep(yticks,'-([\d.]+)','$1S'), '\b[\d\.]+','$0N');
yticks_cell = cellstr(regexp(yticks,'\s+','split'));
set(gca,'YTickLabel',yticks_cell)

second y-axis on pcolor plot

Is it possible to prodce a pcolor plot with 2 yaxis?
Consider the following example:
clear all
temp = 1 + (20-1).*rand(365,12);
depth = 1:12;
time =1:365;
data2 = 1 + (60-1).*rand(12,1);
time2 = [28,56,84,124,150,184,210,234,265,288,312,342];
figure;
pcolor(time,depth,temp');axis ij; shading interp
hold on
plot(time2,data2,'w','linewidth',3);
Instead of plotting the second dataset on the same y axis I would like it to placed on its own y-axis. Is this possible?
You need to add additional axes on the top of pcolor axes, match their position and then plot. You can set axes location on the top (X) and on the right (Y). Don't forget to link X axes if they suppose to match with LINKAXES.
pcolor(time,depth,temp');axis ij; shading interp
ax1 = gca;
%# new axes with plot
ax2 = axes('position',get(ax1,'position'),'color','none');
set(ax2,'YAxisLocation','right', 'XAxisLocation','top')
hold on
plot(ax2,time2,data2,'w','linewidth',3);
hold off
linkaxes([ax1 ax2], 'x');
I am not sure what you mean.
If you want same axes but different y values, try plotyy. If you want two different axes, try using the command subplot.

Plotting a subplot on top of another plot in Matlab

I need to plot several plots along a sloped line at different positions.
For example, if I:
plot(0:200,'k');
plotpts = 5:5:200;
I would like to be able to plot a smaller plot at each of my plotpts on top of the original 0:200 line.
I know you can use hold on and plot over top that way, but I need to change my origin each time. Does anyone have any suggestions? I would really like to stay in matlab. Thanks!
Here is a flexible way I usually do it:
plot(1:10, 'k')
plotpts = 2:2:8;
mainbox = get(gca, 'Position');
xlims = get(gca, 'XLim');
ylims = get(gca, 'Ylim');
for i=1:length(plotpts)
originx = mainbox(1) + (plotpts(i) - xlims(1)) * (mainbox(3)) / (xlims(2) - xlims(1));
originy = mainbox(2) + (plotpts(i) - ylims(1)) * (mainbox(4)) / (ylims(2) - ylims(1));
axes('position', [originx originy 0.1 0.1], 'Color', 'none')
% Do some plotting here...
end
It's quite a bit of work, but you probably want to use the axes command. A figure window can host any number of axes, where each axes has it's own position, data, annotations, color etc.
The most difficult thing for the application you describe is that each axis position needs to be defined in the coordinate frame of the underlying figure, which means that some math may be required to create the illusion that the axis is correctly positioned within a parent axes/
For example, if you first create a simple plot
figure(1234); clf;
plot(1:10, rand(1,10),'.k-','linewidth',5);
xlim([1 10]);
ylim([0 1]);
set(gca,'color','y'); %This just helps demonstrate the next steps
You can place another axis directly on top of the first, and then
ha = axes('position',[.2 .3 .1 .1])
plot(linspace(0,2*pi,100), sin(linspace(0,2*pi,100)), 'b-')
xlim([0 2*pi])
You can adjust the the properties of the inset axis to suit your particular needs, for example
set(ha,'color','none'); %A transparent axis
set(ha,'xtick',[],'ytick',[]); %Remove tick labels
title(ha,'This is an inset plot')
Is the command subplot not what you're looking for?

Add legend outside of axes without rescaling in MATLAB

I've got a GUI in MATLAB with a set of axes pre-placed. I'm using the location property of the legend to place it to the right hand side of the axes. However, by doing this the axes get re-scaled so that the axes+legend take up the original width of the axes. Is there any way to circumvent the re-size?
Example:
x=0:.1:10;
y=sin(x);
figure
pos=get(gca,'position');
pos(3)=.5; %#re-size axes to leave room for legend
set(gca,'position',pos)
plot(x,y)
So far I get:
Place legend:
legend('sin(x)','location','eastoutside')
...aaaaand...
MATLAB squishes it all into the original axes space. Any way around this?
EDIT
%# create three axes with custom position
x=0:.1:10;
y=sin(x);
hAx1 = axes('Position',[0.05 0.05 0.7 0.2]); plot(hAx1, x,y)
hAx2 = axes('Position',[0.05 0.4 0.7 0.2]); plot(hAx2, x,y)
hAx3 = axes('Position',[0.05 0.75 0.7 0.2]); plot(hAx3, x,y)
%# add legend to middle one
h = legend(hAx2, 'sin(x)'); pos = get(h,'position');
set(h, 'position',[0.8 0.5 pos(3:4)])