Question

Too many grid lines in log plot

When I add grid lines to a log plot, it seems to automatically add every possible grid line, and I would like to only include the major lines. I tried turning the minor ticks off, but it has no effect.

For example:

loglog([0.000001,0.1],[0.000001,0.1])
grid on
gca.YAxis.MinorTick = 'off'

enter image description here

How can I just have grid lines at the labelled axes ticks?

 5  94  5
1 Jan 1970

Solution

 5

The loglog plot has unusual axes, because the minor tickmarks are enabled by default as you'd normally expect from the major tickmarks. So this behaviour from the grid documentation is a bit of a grey area:

grid on displays the major grid lines for the current axes returned by the gca command. Major grid lines extend from each tick mark.

Note that most of the plots in the documentation for loglog use grid on and show the minor(ish) grids as you're seeing, so I doubt this is unexpected behaviour from MathWorks' perspective.

Since there's no way to call grid whilst explicitly disabling the minor grid lines, (as it should be the default behaviour), you'll have to manage the grids more granularly with set after creating the axes. You can enable the major grids and disable the minor grids in one command without using grid() at all...

Tested in R2020b Update 5:

loglog([0.000001,0.1],[0.000001,0.1])
set(gca,'xminorgrid','off','yminorgrid','off','xgrid','on','ygrid','on')

plot without minor gridlines


Edit: From conversation in the comments, Luis suggested that grid on, grid minor should work. However, testing in R2020b it does not. Calling these commands in two separate calls does work the same way as using set above:

loglog([0.000001,0.1],[0.000001,0.1])
grid on
grid minor

I assume because the graphics buffer has to be flushed before grid minor works to remove gridlines, maybe because if not there's nothing there to remove. You could disguise this as a single line using drawnow to flush the buffer, but at that point I think I'd recommend just using set shown above

loglog([0.000001,0.1],[0.000001,0.1])
grid on; drawnow(); grid minor

Speculating, maybe the author of loglog decided the minor grids with their variable spacing made the plot look more "logish"? i.e. it's more obviously a nonlinear scale.

2024-06-28
Wolfie

Solution

 4

The grids follow the ticks, so

loglog([0.000001,0.1],[0.000001,0.1])
grid on
set(gca(),'XTick',logspace(-6,-1,6),'YTick',logspace(-6,-1,6),'XMinorGrid','off','YMinorGrid','off')

give you

enter image description here

2024-06-28
X Zhang

Solution

 2

The other answers provide solutions, but do not explain why your code does not work. For clarity, it should be noted first that

  • the gca function gives the current axes object;
  • the property YAxis of the latter refers to a numeric ruler object, which is a child of the axes.

There are two problems with your code. The first problem is that

gca.YAxis.MinorTick = 'off'

does not set a property of the numeric ruler within the current axes. You cannot directly apply dot indexing to a function output; you need to do one of the following:

  • assign it first to a variable:

    a = gca;
    a.YAxis.MinorTick = 'off';
    
  • use parentheses (thanks, @CrisLuengo!)

    gca().YAxis.MinorTick = 'off';
    
  • use get and set (more cumbersome):

    set(get(gca, 'YAxis'), 'MinorTick', 'off')
    

What your code does is to create a struct called gca (thus shadowing the function with the same name) with the specified field, subfield and value. Not useful.

The second problem is that the MinorTick property of the numeric ruler only affects the minor ticks, not the minor grid lines. What you want to set is the YMinorGrid property of the current axes. So,

a = gca;
a.YMinorGrid = 'off';

does what you want.

2024-06-28
Luis Mendo