Matthias Pospiech
Matthias Pospiech

Reputation: 3488

matlabs plotyy with axis for each plot only on one side

The following code shows my problem. plotyy completely fails if the ticks are not at the same positions on both sides (which is rather the normal case...)

I require a plot with two y axis but the ticks only on one side. I was suggested to use addaxis, but I do not see how that helps me, since I do not want separated axis.

clf;
clc;
xaxis = 0:0.1:25;
ydata1 = linspace(12.1712,12.7679, length(xaxis));
ydata2 = linspace(0.3597,-28.7745, length(xaxis));

[AX,H1,H2] = plotyy(xaxis, ydata1, xaxis, ydata2);

% axis limits - x axis (min to max)
xlimits(1) = min(xaxis); xlimits(2) = max(xaxis);
set(AX, 'XLim', xlimits);
set(AX(2),'XTick',[]);

% y1 axis limits 
ylimits(1) = min(ydata1); ylimits(2) = max(ydata1);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
set(AX(1), 'YLim', ylimits);

% y2 axis limits 
ylimits(1) = min(ydata2); ylimits(2) = max(ydata2);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
set(AX(2), 'YLim', ylimits);

% y1 ticks 
set(AX(1),'YTick',[12.0:0.1:12.8]);
% y2 ticks 
set(AX(2),'YTick',[-25:5:0]);

print(gcf, ['-r' num2str(400)], ['test' '.png' ], ['-d' 'png']);

enter image description here

Upvotes: 5

Views: 4627

Answers (4)

embert
embert

Reputation: 7592

Here is a solution using a third axis. For this solution first turn boxes of as suggested

set(ax(1),'Box','off') % Turn off box of axis 1, which removes its right-hand ticks
set(ax(2),'Box','off') % Turn off box of axis 2, which removes its left-hand ticks

Now, additionally add a third axis at the same position.

    ax3 = axes( 'Position',         get(ax(1), 'Position'),...
                'XAxisLocation',    'top',...
                'XTickLabel',       my_XTickLabels_on_top,...
                'YColor',           'none',...
                'YTick',            [],...
                'YTickLabel',       [],...
                'Color',            'none', ...
                cell_with_further_pValPairs{:});

One can also link the 'x' axis of all axes objects. The limits and ticks will then get updated accordingly.

    linkaxes([ax ax3], 'x')

This will, however, not properly update the ticks of the third axis, unless you write a proper callback, which got even more tricky to do in MATLAB 2014b and above To make the 'real' axes the current axes, it is possible to use

    axes(ax)

Example:

enter image description here

Upvotes: 0

Ping Du
Ping Du

Reputation: 21

to Matthias,

set the XAxisLocation to top, and disable the XTickLabel. the upper line is back now :)

set(AX(2),'XAxisLocation','top', 'XTickLabel',[])

Upvotes: 2

Matthias Pospiech
Matthias Pospiech

Reputation: 3488

Here is an approach that I got from the mathworks forum. The idea is to remove the box property, which creates the tics on the opposite side.

set(AX(1),'Box','off') % Turn off box of axis 1, which removes its right-hand ticks
set(AX(2),'Box','off') % Turn off box of axis 2, which removes its left-hand ticks

The downside is, that the upper line disappears. If someone knows how to get it back that would be great. Mybe with an empty plot over the current plot with the same dimensions??

enter image description here

Upvotes: 0

Andrey Rubshtein
Andrey Rubshtein

Reputation: 20915

Try setting the ticks to empty set:

 set(AX(2),'YTick',[]);

or

 set(AX(1),'YTick',[]);

Edit(1): You can manually create the labels for left side and set the right side to []:

clf;
clc;
xaxis = 0:0.1:25;
ydata1 = linspace(12.1712,12.7679, length(xaxis));
ydata2 = linspace(0.3597,-28.7745, length(xaxis));

[AX,H1,H2] = plotyy(xaxis, ydata1, xaxis, ydata2);

% axis limits - x axis (min to max)
xlimits(1) = min(xaxis); xlimits(2) = max(xaxis);
set(AX, 'XLim', xlimits);
set(AX(2),'XTick',[]);

% y1 axis limits 
ylimits(1) = min(ydata1); ylimits(2) = max(ydata1);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
set(AX(1), 'YLim', ylimits);

x  = linspace(ylimits(1),ylimits(2),10);
ticks1 =  arrayfun(@(t){sprintf('%2.2f',t)},x);


% y2 axis limits 
ylimits(1) = min(ydata2); ylimits(2) = max(ydata2);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
x  = linspace(ylimits(1),ylimits(2),10);
ticks2 =  arrayfun(@(t){sprintf('%2.2f',t)},x);
set(AX(2), 'YLim', ylimits);

ticks = cell(size(ticks1));
for i=1:numel(ticks1)
    ticks{i} = sprintf('%s / %s',ticks1{i},ticks2{i});
end
% y1 ticks 
set(AX(1),'YTickLabel',ticks);
% % y2 ticks 
set(AX(2),'YTick',[]);

Upvotes: 0

Related Questions