Changing Some MATLAB Plotting Defaults

During my last five years at MathWorks, one of my Steve on Image Processing blog posts consistently had the most web traffic—and by a large margin. It amused me that the post had nothing to do with image processing. It was called "Making your plot lines thicker," and it opened with this plot:

a pursuit-curve plot with thick red and blue lines

As I explained in that 22-Feb-2019 post, I think that lines in MATLAB plots are too thin (0.5 points) by default. I prefer thicker plot lines, and so I set the default line width to 2 points in my startup file:

set(groot,'DefaultLineLineWidth',2)

(For information on how to change default graphics property values, and how to do that automatically when MATLAB starts, see these doc pages: Default Property Values, startup, and userpath.)

I have recently changed two more default plotting behaviors to suit my own preference, and I want to tell you about them:

  • The axes limit method
  • The axes grid

Axes Limit Method

Before I explain the axes limit method, I'll restore the MATLAB factory plotting defaults (see the end of this post for the factoryPlottingDefaults function) so that you see what MATLAB plots normally look like:

factoryPlottingDefaults

Here's an example:

x = 0:pi/100:2*pi;
y1 = sin(x);
y2 = cos(x);
plot(x,y1,x,y2)

sine and cosine, default plot behavior

MATLAB has chosen 0 and 7 as the x-axis limits, and -1 and 1 as the y-axis limits. Notice that the plotted data goes all the way to the left, bottom, and top edges of the plot box. What makes that happen?

Those values are chosen according to the XLimitMethod and YLimitMethod properties of the axes.

ax = gca;
ax.XLimitMethod
ans = 'tickaligned'
ax.YLimitMethod
ans = 'tickaligned'

According to the Axes Properties doc page, the tickaligned method aligns "the edges of the axes box with the tick marks that are closest to your data without excluding any data." The MATLAB tick-label method tries to pick ticks with nice round numbers (for some definition of "nice round number"). Since the minimum x value of the plotted data is exactly 0, and the minimum and maximum y values are exactly -1 and 1, the limits are exactly at the tick labels, and that's why the plots go all the way to the left, bottom, and top edges of the box.

I've been using MATLAB for so long that I was just used to this behavior without thinking about it. A few years ago, though, some design discussions at MathWorks made me realize that it might not always be a good idea for data to crowd the edges of the plot box.

For example, take a look at this real plot, (saved from a previous project of mine) and ask yourself, "Is there a peak at x=0? If so, how high does it go?"

sample plot with data crowding left and top edges of box

You really can't tell unless you reduce the lower limit so the data doesn't crowd the box:

sample plot with extra space added between data and left and right box edges

Now you can tell that the peak at x=0 is roughly around 1650. There is a similar problem with determining the height of the peak at x=500. The peak appears to go to 2000, but there is a x-tick at the top of the box there, so you can't be sure.

Since R2021a, there has been a way to choose axes limits so that there is a small amount of space between the data and the plot box. You can do this by calling axis padded.

plot(x,y1,x,y2)
axis padded

sine and cosine with axis padding

This is equivalent to setting the XLimitMethod and YLimitMethod properties of the axes to "padded". You can set these in your startup file:

set(groot,"DefaultAxesXLimitMethod","padded")
set(groot,"DefaultAxesYLimitMethod","padded")

I want to like the plot above, but, sadly, I don't. I find myself looking at the data and wondering if it goes exactly to 0, or exactly to 1, or exactly to -1, and it's diffcult to tell. And that brings me to the second recent change I have made to MATLAB default plotting behavior.

Axes Grid

I turn the grid on.

plot(x,y1,x,y2)
axis padded
grid on

sine and cosine with axis padding, grid on

That's much better, and very close to what I'd like to see. The last change I'll make here is the first one I mentioned—the line width.

plot(x,y1,x,y2,LineWidth = 2)
axis padded
grid on

sine and cosine with axis padding, grid on, LineWidth=2

Very good. That's what I want my MATLAB plots to look like. To make that happen automatically, I have put the following code into my startup file:

set(groot,"DefaultLineLineWidth",2)
set(groot,"DefaultAxesXLimitMethod","padded")
set(groot,"DefaultAxesYLimitMethod","padded")
set(groot,"DefaultAxesZLimitMethod","padded")
set(groot,"DefaultAxesXGrid","on")
set(groot,"DefaultAxesYGrid","on")
set(groot,"DefaultAxesZGrid","on") 

Design History Speculation

I think these default MATLAB behaviors, which I now prefer to change, originated approximately 35 years ago, at a time when computer monitors had much less resolution than they do now. You couldn't actually draw a 0.5-point line on those monitors because the individual pixels were bigger than that. You could print thin lines, though, on the laser printers of the time, so it was useful to have "0.5-point" lines, even if they weren't really that thin on the screen.

The inability to draw very thin lines probably influenced the decision, at that time, to not turn on the grid by default. And with low screen resolutions of 800x600, or even 640x480, screen pixels were too scarce and valuable to "waste" by putting a little padding between the data and the box.

Now, in the world of high-resolution displays, I think it would be appropriate for MathWorks to consider changing some of these defaults, even at the risk of causing some compatibility issues.

Utility Function for this Post

function factoryPlottingDefaults
    set(groot, "DefaultLineLineWidth", 0.5)
    set(groot,"DefaultAxesXLimitMethod","tickaligned")
    set(groot,"DefaultAxesYLimitMethod","tickaligned")
    set(groot,"DefaultAxesZLimitMethod","tickaligned")
    set(groot,"DefaultAxesXGrid","off")
    set(groot,"DefaultAxesYGrid","off")
    set(groot,"DefaultAxesZGrid","off")     
end