# [Plotting] Two x and y axes for the same data, with different units, and axis equal

42 views (last 30 days)

Show older comments

Hello all,

I have asked a similar question before, but have yet to find/create a satisfactory solution. I am attempting to plot position data that comes in latitude-longitude. These are over a relatively small area, so there is a direct conversion from lat/lon into meters N/E relative to some reference point. I am attempting to plot the data with the meters-E and meters-N on the x and y axes respectively. I want a second pair of xx and yy axes on the top and right side respectively plotting the latitude and longitude. This I have managed to do. The sticking point is that I want to lock the figure to equal axes in x-y direction in meters so that the data has a realistic aspect ratio. This then kills the second pair of axes. Two sample image, and then some pseudo-code below:

Here we can see what I am going for with two major problems: the y-tick labels are cut-off on the right side, and the x-y axes are squished.

Now, I use axis equal on the first axes (the one in meters). This actually has the correct aspect ratio, but you can see that the second axies has not remained locked with the first. This is bad.

This whole process is really kludgey. The closest I got was to add a pbaspect command to the second axes and I get. It is still definitely not correct.

I am simply floored that there isn't really a way to have multiple axes for the same data. I will attach a gross code example below, and hope that someone has a suggestion. The core technique was suggested in this Mathworks page.

% Lat/lon, convert to meters

lat0 = 51.2697; % deg

lon0 = -77.3379; % deg

dLat = 1.5696e-07; %meters/radian lat here

dLon = 2.5087e-07; %meters/radian lon here

% Set up some random walk

dx = rand(100,1);

dy = rand(100,1);

x = cumsum(dx);

y = cumsum(dy);

% Convert that to lat/lon

lat = 360/(2*pi)*y*dLat + lat0;

lon = 360/(2*pi)*x*dLon + lon0;

% Plot our walk in meters

close all

figure();

plot(x,y,'b.');

xlabel('Easting (m)');

ylabel('Northing (m)');

set(gca,'box','off')

% Set axes as equal.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% comment out for other option

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

axis equal; axis tight;

% Suggested by Mathworks

ax1 = gca; % current axes

ax1_pos = ax1.Position; % position of first axes

ax2 = axes('Position',ax1_pos,...

'XAxisLocation','top',...

'YAxisLocation','right',...

'Color','none');

% Super Kludge, try to set our x/y-ticks

xt = xticks;

yt = yticks;

% Only grab 1/3 of them for spacing

xticks(xt(1:3:end));

yticks(yt(1:3:end));

xt = xticks;

yt = yticks;

% Set up some tick labels

latL = linspace(min(lat),max(lat),length(xt));

lonL = linspace(min(lon),max(lon),length(yt));

xticklabels(lonL);

yticklabels(latL);

% TRY to fix our aspect ratio issue.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% comment out for other option

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pbaspect([dLat/dLon,1,1]);

##### 0 Comments

### Accepted Answer

Cris LaPierre
on 14 Feb 2019

Edited: Cris LaPierre
on 15 Feb 2019

You are not setting the same properties on ax2 as ax1 (axis equal; axis tight). However, position of an axis does not change with 'axis tight', but plotting canvas does. This will cause the two axes to still be unaligned. If you don't do axis tight, you'd get this:

Here's the code I used

% Lat/lon, convert to meters

lat0 = 51.2697; % deg

lon0 = -77.3379; % deg

dLat = 1.5696e-07; %meters/radian lat here

dLon = 2.5087e-07; %meters/radian lon here

% Set up some random walk

dx = rand(100,1);

dy = rand(100,1);

x = cumsum(dx);

y = cumsum(dy);

% Convert that to lat/lon

lat = 360/(2*pi)*y*dLat + lat0;

lon = 360/(2*pi)*x*dLon + lon0;

% Plot our walk in meters

close all

figure();

scatter(x,y,'b.');

xlabel('Easting (m)');

ylabel('Northing (m)');

set(gca,'box','off')

% Set axes as equal.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% comment out for other option

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

axis equal;

% axis tight;

% Suggested by Mathworks

ax1 = gca; % current axes

ax1_pos = ax1.Position; % position of first axes

ax2 = axes('Position',ax1_pos,...

'XAxisLocation','top',...

'YAxisLocation','right',...

'Color','none');

axis equal

% axis tight

% Add labels

ax1Xtck = ax1.XTick';

ax1Ytck = ax1.YTick';

ax2.XTickLabel = num2str(interp1(x,lon,ax1Xtck,'linear','extrap'));

ax2.YTickLabel = num2str(interp1(y,lat,ax1Ytck,'linear','extrap'));

##### 4 Comments

Cris LaPierre
on 15 Feb 2019

Edited: Cris LaPierre
on 11 Nov 2020

### More Answers (0)

### See Also

### Categories

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!