13

I'm using the following to display the minor grid in my plot:

grid(gca,'minor') 
set(gca,'MinorGridLineStyle','-')

but I'd like to change the color of the grid lines to a nice greyscale. I can't find any option 'grid color' in matlab... Do you know any or any workaround? I found this: http://www.mathworks.com/matlabcentral/fileexchange/9815-gridcolor but as I read of the comments, it doesn't work very well and further it only changes gridcolor, not the color of the minor grid... Thanks!


EDIT: Problem with semilogx as posting here now:

x = [1e-9 1e-8 1e-7 1e-6 1e-5 1e-4 1e-3 1e-2]';
y1 = linspace(20, 90, 8);
y2 = y1.^2;
y3 = y1./y2+5;

% plotte: http://www.mathworks.com/help/techdoc/ref/linespec.html
myfig = figure('Position', [500 500 445 356]); %[left, bottom, width, height]:
p1 = semilogx(x,y1,'x--r',x,y2,'*-b');

ax1 = gca;
set(ax1, 'Position',[0.13 0.18 0.75 0.75]);

xlim([0 max(x)]);
ylim([0 max([max(y1) max(y2)])]);


col=.85*[1 1 1];
%# create a second transparent axis, same position/extents, same ticks and labels
ax2 = axes('Position',get(ax1,'Position'), ...
    'Color','none', 'Box','on', ...
    'XTickLabel',get(ax1,'XTickLabel'), 'YTickLabel',get(ax1,'YTickLabel'), ...
    'XTick',get(ax1,'XTick'), 'YTick',get(ax1,'YTick'), ...
    'XLim',get(ax1,'XLim'), 'YLim',get(ax1,'YLim'),...
    'XScale', 'log');

%# show grid-lines of first axis, give them desired color, but hide text labels
set(ax1, 'XColor',col, 'YColor',col, ...
    'XMinorGrid','on', 'YMinorGrid','on', ...
    'MinorGridLineStyle','-', ...
    'XTickLabel',[], 'YTickLabel',[],'XScale', 'log');


%# link the two axes to share the same limits on pan/zoom
linkaxes([ax1 ax2],'xy');

Displaying like this: enter image description here


EDIT2: A problem occurs when adding a second y-axes as in the following picture, look at the ticks of the right y-axes:

enter image description here

this will be discussed here to have a better overview! Matlab: Problem with ticks when setting minor grid style and two y-axis

Community
  • 1
  • 1
tim
  • 9,896
  • 20
  • 81
  • 137

4 Answers4

10

Set the 'XColor','YColor' axes properties. Note that these properties determine the color of the axis lines, tick marks, tick mark labels, and the axis grid lines, so AFAIK you can't assign those different colors than that of the entire axis..

Example:

plot(rand(10,1))
set(gca, 'XMinorGrid','on', 'YMinorGrid','on', 'XColor','r', 'YColor','g')

EDIT1:

You can always create a second transparent axis with the desired grid colors, but with no ticks or labels, stacked on top of the current axis. Here is an example:

%# create plot as usual
plot(rand(10,1))
hAx1 = gca;

%# create a second axis, same position/extents, no tick or labels, colored grid-lines
hAx2 = axes('Position',get(hAx1,'Position'), ...
    'Color','none', 'TickLength',[1e-100 1e-100], ...
    'XMinorGrid','on', 'YMinorGrid','on', ...
    'Box','off', 'XColor','g', 'YColor','r', ...
    'XTickLabel',[], 'YTickLabel',[], ...
    'XTick',get(hAx1,'XTick'), 'YTick',get(hAx1,'YTick'), ...
    'XLim',get(hAx1,'XLim'), 'YLim',get(hAx1,'YLim'));

%# position it on top
%#uistack(hAx2,'top')

%# redraw the enclosing box in the original axis colors
x = get(hAx1,'XLim');
y = get(hAx1,'YLim');
line([x([1 2]) nan x([2 1])],[y([1 1]) nan y([2 2])],'Color',get(hAx1,'XColor'))
line([x([1 1]) nan x([2 2])],[y([1 2]) nan y([2 1])],'Color',get(hAx1,'YColor'))

The only problem is that the grid lines are drawn on top of your plot, which might get in the way if the grid-lines are thick :)

edit1_screenshot


EDIT2:

Seems like @yoda had a similar idea to the above. Here is a slightly improved version inspired by his solution:

%# create plot as usual
plot(11:20, rand(10,1)*5)
hAx1 = gca;   %# get a handle to first axis

%# create a second transparent axis, same position/extents, same ticks and labels
hAx2 = axes('Position',get(hAx1,'Position'), ...
    'Color','none', 'Box','on', ...
    'XTickLabel',get(hAx1,'XTickLabel'), 'YTickLabel',get(hAx1,'YTickLabel'), ...
    'XTick',get(hAx1,'XTick'), 'YTick',get(hAx1,'YTick'), ...
    'XLim',get(hAx1,'XLim'), 'YLim',get(hAx1,'YLim'));

%# show grid-lines of first axis, give them desired color, but hide text labels
set(hAx1, 'XColor','g', 'YColor','r', ...
    'XMinorGrid','on', 'YMinorGrid','on', ...
    'XTickLabel',[], 'YTickLabel',[]);

%# link the two axes to share the same limits on pan/zoom
linkaxes([hAx1 hAx2],'xy');

%# lets create a legend, and some titles
legend(hAx1, 'text')
title('title'), xlabel('x'), ylabel('y')

edit2_screenshot


EDIT3 (take 2):

Here is the same example but with a log-scale x-axis. Note how instead of creating a second axis and manually setting its properties to match the first, I simply copyobj the axis, and delete its children.

%# create a plot as usual (x-axis is in the log-scale)
semilogx(logspace(0,5,100), cumsum(rand(100,1)-0.5))
xlabel('x'), ylabel('y'), title('text')
legend('plot')

%# capture handle to current figure and axis
hFig = gcf;
hAx1 = gca;

%# create a second transparent axis, as a copy of the first
hAx2 = copyobj(hAx1,hFig);
delete( get(hAx2,'Children') )
set(hAx2, 'Color','none', 'Box','on', ...
    'XGrid','off', 'YGrid','off')

%# show grid-lines of first axis, style them as desired,
%# but hide its tick marks and axis labels
set(hAx1, 'XColor',[0.9 0.9 0.9], 'YColor',[0.9 0.9 0.9], ...
    'XMinorGrid','on', 'YMinorGrid','on', 'MinorGridLineStyle','-', ...
    'XTickLabel',[], 'YTickLabel',[]);
xlabel(hAx1, ''), ylabel(hAx1, ''), title(hAx1, '')

%# link the two axes to share the same limits on pan/zoom
linkaxes([hAx1 hAx2], 'xy');

%# Note that `gca==hAx1` from this point on...
%# If you want to change the axis labels, explicitly use hAx2 as parameter.

You should get the correct plot in your example with this code. However I think the x variable values you choose might be too close in the current figure size to show all the vertical lines (simply maximize the figure to see what I mean)...

edit3_screenshot

To get a better idea of what each axis contains, here is a divided view where the plot on the left contains only the graphics rendered by hAx1, while the plot on right contains only the hAx2 components. Those two views are basically overlayed on top of each other in the final figure shown before.

edit3_screenshot_divided_axes

Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • Thanks, the second example is quite nice. Isn't there a way to somehow display the grid 'behind'? Because it's drawn on top of the legend which is really ugly... Perhaps there's a way similar to my above posted? – tim Jul 05 '11 at 13:19
  • Okay I could get yours to work by doing the following: Plot the data, create the second axis and replot the data (I know it's quite ugly but it works) and at the end: draw the legend (it's drawn OVER everything). ONLY REMAINING PROBLEM: The ticks disappear (ticks on the axes) – tim Jul 05 '11 at 13:24
  • @ColHeather: see the latest edit, the grid-lines are now drawn behind the plot, legend and titles are added as well... – Amro Jul 05 '11 at 13:26
  • Okay thanks again! That works pretty nice. But when I add a second y-axis on the right side, it has the ticks of itself and the y-ticks of the left y-axis which is no good. Any way around this also? Thanks! Edit: Example code posted above!!!! – tim Jul 05 '11 at 13:43
  • @ColHeather: I think that should be posted as a separate new question: "I have ..., but I'm having problems when adding a second y-axis", we don't want to confuse other readers who might find this useful as it is... – Amro Jul 05 '11 at 13:57
  • Okay I will co it now and hopefully I will get an answer of you :) Because those are really nice! Here: http://stackoverflow.com/questions/6584105/matlab-problem-with-ticks-when-setting-minor-grid-style-and-two-y-axis – tim Jul 05 '11 at 14:10
  • And therer's another problem with using `semilogx`, which I edited into the first post because it's not related to the second y-axis problem but to this problem discussed here. Thannks a lot Amro in advance! – tim Jul 05 '11 at 14:27
  • @ColHeather: fixed the log-scale issue here, still working on the other question :) – Amro Jul 05 '11 at 15:05
  • Wow great job, I'm testing it out! thanks, I would be really messed up without you... And without all the other helpers! – tim Jul 05 '11 at 15:14
  • @Amro feel free to rollback, if you prefer to see my edit as a separate answer. But as your approach was not immediately working for me, it made this improvements necessary and its also more versatile now. – Robert Seifert May 27 '14 at 09:38
  • 1
    @thewaywewalk: Thanks for the edit. I incorporated your changes into the existing example, with a few additions. – Amro May 27 '14 at 14:48
  • @Amro looks nice, I will also try it out! – Robert Seifert May 27 '14 at 15:24
6

Unfortunately, while the trick of over- or under-laying a second, gridded axes mostly works, Matlab does not render it properly when you save to a PDF file. This is because Matlab does not support transparency in PDFs.

One workaround is to simply use line to draw in the grid lines one by one:

for dir='XY';
    ticks = get(gca, [dir 'Tick']);
    lim = get(gca, [dir 'lim']);
    for ii=1:length(ticks)
        coord = ticks(ii);

        for jj=1:9,
            if jj==1                  % major grid properties
                color = [1 1 1]*0.9;
                weight = 2;
            else                      % minor grid properties
                color = [1 1 1]*0.9;
                weight = 1;
            end
            if jj*coord > lim(2)
                continue
            end
            if dir=='X' 
                L = line((jj*coord)*[1 1], get(gca, 'ylim'), ...
                         'color', color, 'linewidth', weight);
            else
                L = line(get(gca, 'xlim'), (jj*coord)*[1 1], ...
                         'color', color, 'linewidth', weight);
            end
            uistack(L, 'bottom');
        end
    end
end

One downside of this approach is that it overwrites the tick marks and plot boundary box. A solution to this is to combine this approach with the trick of under-laying a second axes. Draw the fake grid on the underlying axes. This IS rendered properly in PDF:

enter image description here

nibot
  • 14,428
  • 8
  • 54
  • 58
3

While Amro is right that the minor grid's color is the same as that of the axis labels, you can always turn off the axis labels and overlay a second axes with transparent filling and set the labels on that in a different color. Here's a small example showing how:

plot(rand(10,1))
xTicks=get(gca,'xTick');
yTicks=get(gca,'ytick');
set(gca, 'XMinorGrid','on', 'YMinorGrid','on',...
    'XColor','r', 'YColor','g','xticklabel',[],'yticklabel',[],...
    'box','off')

h2=axes;
set(h2,'color','none','xtick',linspace(0,1,numel(xTicks)),'xticklabel',xTicks,...
    'ytick',linspace(0,1,numel(yTicks)),'yticklabel',yTicks)

enter image description here

abcd
  • 41,765
  • 7
  • 81
  • 98
2

This lets you set independent colors for major and minor X and Y grid lines, without overwriting the outer box. Even better, subsequent legend() commands will pick up the plot lines, not the manually drawn grid lines.

The trick is to make copies of the axes, then reverse their order in the figure's drawing hierarchy. Each copy of the axes can then draw its own set of grid colors and styles.

This strategy is compatible with subplot() and print().

function gridcolor(majorX, majorY, minorX, minorY)

ax1 = gca;   %# get a handle to first axis

%# create a second transparent axis, same position/extents, same ticks and labels
ax2 = copyobj(ax1,gcf);
ax3 = copyobj(ax1,gcf);

delete(get(ax2,'Children'));
delete(get(ax3,'Children'));

set(ax2, 'Color','none', 'Box','off','YTickLabel',[],'YTickLabel',[],...
    'GridLineStyle', '-',...
    'XGrid','on','YGrid','on',...
    'XMinorGrid','off','YMinorGrid','off',...
    'XColor',majorX,'YColor',majorY);
set(ax3,'Box','off','YTickLabel',[],'YTickLabel',[],...
    'MinorGridLineStyle','-',...
    'XGrid','off','YGrid','off',...
    'XMinorGrid','on','YMinorGrid','on',...
    'XColor',minorX,'YColor',minorY);

set(ax1, 'Color','none', 'Box','on')

handles = [ax3; ax2; ax1];
c = get(gcf,'Children');
for i=1:length(handles)
    c = c(find(c ~= handles(i)));
end
set(gcf,'Children',[c; flipud(handles)]);

linkaxes([ax1 ax2 ax3]);
end

subplot(211);semilogx([1:4000]);gridcolor('r','g','c','b');
subplot(212);semilogx(([1:4000]).^-1);gridcolor('r','g','c','b');

Screenshot demonstrating gridcolor()

Shanti
  • 1,230
  • 1
  • 9
  • 7