How to set the grid of the right yyaxis?

I have a figure that has 2 yyaxis, and I want the grid shown on the right yyaxis. But the command grid on is only effective on the left yyaxis.
Sure I can just plot the lines of the grids, but the lines are on the top of the other lines or patches. The good thing of the grid is that they are always on the bottom layer, while the lines user plotted are on the top layer.
x1=[200, 300, 250, 520, 340];
x2=[0.3, 0.2, 0.12, 0.4, 0.22];
figure;
yyaxis left
bar(x1);
yyaxis right
plot(x2);
grid on
The grid is on the left yyaxis, while I want it to be of the right yyaxis. What should I do?

2 comentarios

KALYAN ACHARJYA
KALYAN ACHARJYA el 1 de Dic. de 2020
Editada: KALYAN ACHARJYA el 1 de Dic. de 2020
Answer from MATLAB "Grid lines correspond with the tick mark locations along the left y-axis". Option plotyy
Albert Bing
Albert Bing el 1 de Dic. de 2020
Thanks for the answer.
I checked the 2 solutions.
1. plotyy is not recommended since R2016a and it doesn't seem to apply to the bar command or patches.
2. yyaxis command gives the axes 2 YAxis but only one YGrid. And it always worked on the left yyaxis.

Iniciar sesión para comentar.

 Respuesta aceptada

Star Strider
Star Strider el 1 de Dic. de 2020
Editada: Star Strider el 1 de Dic. de 2020
Another option is to create new right-axis tick positions to match the tick positions on the left:
x1=[200, 300, 250, 520, 340];
x2=[0.3, 0.2, 0.12, 0.4, 0.22];
figure;
yyaxis left
bar(x1)
ytl = get(gca, 'YTick'); % Get Controlling Left Ticks
yyaxis('right');
plot(x2)
ytr = get(gca, 'YTick'); % Get Right Tick Values
ytrv = linspace(min(ytr), max(ytr), numel(ytl)); % Create New Right Tick Values Matching Number Of Left Ticks
ytrc = compose('%.2f',ytrv); % Tick Label Cell Array
set(gca, 'YTick',ytrv, 'YTickLabel',ytrc) % Set New Right Tick Labels
grid on
producing:
.
EDIT — (1 Dec 2020 at 17:48)
To get ticks and tick labels with more rational spacing:
x1=[200, 300, 250, 520, 340];
x2=[0.3, 0.2, 0.12, 0.4, 0.22];
figure;
yyaxis left
bar(x1)
ytl = get(gca, 'YTick'); % Get Controlling Left Ticks
yyaxis('right');
plot(x2)
ytr = get(gca, 'YTick'); % Get Right Tick Values
tinc = diff(ylim)/numel(ytl); % Tick Increment
ytrv = min(ylim):tinc:(tinc*(numel(ytl)+1));
ylim([min(ytrv) max(ytrv)]) % Set New ‘ylim’
ytrc = compose('%.2f',ytrv); % Tick Label Cell Array
set(gca, 'YTick',ytrv, 'YTickLabel',ytrc) % Set New Right Tick Labels
grid on
producing:
.

3 comentarios

Or
ax = gca();
ax.YTick = ytrv;
ax.YAxis(2).TickLabelFormat = '%.2f';
Albert Bing
Albert Bing el 1 de Dic. de 2020
Thanks very much!
The aligned yyaxis solusion is better. The codes might be run on some older versions of MATLAB.
Star Strider
Star Strider el 1 de Dic. de 2020
As always, my pleasure!

Iniciar sesión para comentar.

Más respuestas (1)

Adam Danz
Adam Danz el 1 de Dic. de 2020
Editada: Adam Danz el 1 de Dic. de 2020
As KALYAN ACHARJYA mentioned, the grid lines reference the left axis.
Workaround
Set the vertical grid lines
ax = gca();
ax.XGrid = 'on';
set the horizontal grid lines using yline after setting the ytick and ylim. If the ylim or yticks change, the horizontal reference lines will not update. You could add a listener to fix that. Also, the horizonal lines will always be on top. To put them on the bottom see this answer.
yyaxis right
ylim([-1,3])
ax.YTick = -1:.5:3;
yl = arrayfun(@(y)yline(ax, y,'LineStyle',ax.GridLineStyle,'Color',ax.GridColor,'Alpha',ax.GridAlpha),ax.YTick);

7 comentarios

Albert Bing
Albert Bing el 1 de Dic. de 2020
Editada: Albert Bing el 1 de Dic. de 2020
Thanks. The Xgrid belongs to the right y-axis.
The answer of putting lines on the bottom seems not work. The last line Sxh.Edge.Layer = 'back' throws an error.
I ran the example you gave, and the result was a little wired. The YGrid is on the bottom but the XGrid is still on the top.
x1=[200, 300, 250, 520, 340];
x2=[0.3, 0.2, 0.12, 0.4, 0.22];
figure;
yyaxis left
bar(x1);
yyaxis right
plot(x2);
ax = gca();
ax.XGrid = 'on';
ax.YGrid = 'off';
yyaxis right
ylm = ylim();
yl = arrayfun(@(y) yline(ax, y,'LineStyle',...
ax.GridLineStyle,'Color',ax.GridColor,'Alpha',...
ax.GridAlpha),ax.YTick);
Here is what I got
x1=[200, 300, 250, 520, 340];
x2=[0.3, 0.2, 0.12, 0.4, 0.22];
figure;
yyaxis left
bar(x1);
yyaxis right
plot(x2);
hold on
xh = plot([0 6], [0.2 0.2], 'r-'); % no xline since older version of MATLAB
warnState = warning('off','MATLAB:structOnObject');
cleanupObj = onCleanup(@()warning(warnState));
Sxh = struct(xh);
clear('cleanupObj')
Sxh.Edge.Layer = 'back';
Sxh.Edge is a 0x0 empty GraphicsPlaceholder
Adam Danz
Adam Danz el 1 de Dic. de 2020
> The Xgrid belongs to the right y-axis.
No, the xgrid belongs to the x-axis.
> The answer of putting lines on the bottom seems not work. The last line Sxh.Edge.Layer = 'back' throws an error.
The solution in that answer worked for me and of the OP in that question. You might be applying it incorrectly. I don't see what you did and I don't see that error you received so I can't help you there.
> I ran the example you gave, and the result was a little wired. The YGrid is on the bottom but the XGrid is still on the top.
The image you shared shows the exact opposite. The XGrid is under the bars and the YGrid (yline) is on top of the bars which is expected unless you set the lines to the bottom layer correctly.
Adam Danz
Adam Danz el 1 de Dic. de 2020
You're not applying the solution correctly.
The variable "xh" in my solution refers to the xline objects (in your case, it will be the yline).
Albert Bing
Albert Bing el 1 de Dic. de 2020
Thanks!
I got wrong of pointing the XGrid and YGrid.
The xline and yline commands are quite new, so I need aviod using it. Others might have no acccess to these commands.
Albert Bing
Albert Bing el 1 de Dic. de 2020
After a second thought, your solution might be better. Since the grid is the really "grid", located at the right position, like 0.5, 1.0, 1.5 etc. other than 0.16, 0.22 which are not so obvious for readers.
But I have to run the code on MATLAB older than R2018a. So I can't use xline or yline.
I might have to drop the grid.
Adam Danz
Adam Danz el 1 de Dic. de 2020
Editada: Adam Danz el 1 de Dic. de 2020
You can use plot() or line() instead of yline(). The main difference is that yline will always extend to the axis edges but if xlim is changed then lines produced by plot() or line() may no longer extend to the axis edges. You could over-estimate the edges to mitigate that problem.
Example:
yyaxis right
ax = gca();
ax.XGrid = 'on';
ylim([-1,3])
xl = xlim();
xlExtended = xl + [-range(xl), range(xl)]; % Optional
ax.YTick = -1:.5:3;
hold(ax, 'on')
yl = plot(ax, xlExtended,[ax.YTick',ax.YTick'] ,'LineStyle',ax.GridLineStyle,'Color',[ax.GridColor, ax.GridAlpha],'Marker','none');
xlim(xl)

Iniciar sesión para comentar.

Etiquetas

Preguntada:

el 1 de Dic. de 2020

Editada:

el 1 de Dic. de 2020

Community Treasure Hunt

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

Start Hunting!

Translated by