- Undocumented Matlab - https://undocumentedmatlab.com -

Customizing axes part 2

Posted By Yair Altman On October 15, 2014 | 21 Comments

Last week I explained [1] how HG2 (in R2014b) enables us to customize the axes rulers in ways that were previously impossible in HG1 (R2014a or earlier). Today I will describe other useful undocumented customizations of the HG2 axes:

Baseline

A baseline is a line that has some important meaning. For example, in a plot of the sin function, we might want to place a horizontal baseline at Y=0 or Y=-1, and similarly a vertical baseline at X=0. In HG1, we could do this programmatically using extra line commands (presumably with the additional *LimInclude properties [5]). In HG2 it becomes easier – we can simply update the relevant baseline’s properties: XBaseline, YBaseline and ZBaseLine. All baselines are automatically created with a value of 0, color=gray and Visible=’off’. For example, continuing last week’s example:

HG2 axes Baseline
HG2 axes Baseline

% Create the plot
x = -10:0.1:10;
y = 1e7*sin(x)./x;
hLine = plot(x,y);
hAxes = gca;
% Display the default YBaseline's property values
% Note: there are also plenty of hidden properties that can be gotten with getundoc()
>> hAxes.YBaseline.get
           BaseValue: 0
            Children: []
               Color: [0.15 0.15 0.15]
    HandleVisibility: 'off'
           LineStyle: '-'
           LineWidth: 0.5
              Parent: [1x1 DecorationContainer]
             Visible: 'off'
% Display a horizontal YBaseline with custom color
hAxes.YBaseline.Color = 'b';  % default: [0.15 0.15 0.15]
hAxes.YBaseline.Visible = 'on';  % default: 'off'
% Hide the bottom x-axis, to make the Y-baseline stand out
hAxes.XRuler.Axle.Visible = 'off';  % default: 'on'

Note the horizontal blue Y-baseline. also note how I hid the bottom x-axis, in order to make the Y-baseline stand out.
Translucent colors can be specified by entering a 4-element color vector. For example: [1, 0, 0, 0.5] means a 50%-transparent red.
For extra prominence, you might want to increase the baseline’s LineWidth from its default value of 0.5 to a value of 1 or 2.
Another useful customization is to set a non-zero BaseValue, or a non-solid baseline LineStyle.
While YBaseline is normally a horizontal line that relates to the Y-axis (hAxes.YBaseline.Axis==1), we can make it vertical attached to the X-axis by simply modifying its Axis value to 0 (0=X, 1=Y, 2=Z).
For the record, baselines are matlab.graphics.axis.decorator.Baseline class objects.

BoxFrame

The BoxFrame property controls the “box” lines that surround the plot when we issue a box(‘on’) command. This is normally a simple black square/rectangle for 2D plots, and a simple black background wireframe for a 3D plot. But who said it needs to be boring?

surf(peaks);  % 3D plot
box on;  % standard black box wireframe
boxFrame = get(gca,'BoxFrame');  % or: hAxes.BoxFrame
set(boxFrame, 'XColor','r', 'YColor','b', 'ZColor','g');  % default colors: [0.15 0.15 0.15]

HG2 axes BoxFrame
HG2 axes BoxFrame

The BoxFrame object is a matlab.graphics.axis.decorator.BoxFrame class object that, like the rulers and baseline, can be customized (once the box(‘on’) command has been issued):

>> get(boxFrame)
           AxesLayer: 'bottom'
            BackEdge: [1x1 LineStrip]
            Children: []
           FrontEdge: [1x1 LineStrip]
    HandleVisibility: 'off'
           LineWidth: 0.5
              Parent: [1x1 DecorationContainer]
             Visible: 'off'
              XColor: [0.15 0.15 0.15]
              YColor: [0.15 0.15 0.15]
              ZColor: [0.15 0.15 0.15]

By default, only the box frame’s back-edge is displayed (axes BoxStyle property =’back’). We can modify this behavior by setting the axes’ BoxStyle to ‘full’, but we can have much more control if we simply update the properties of the box-frame object. For example:

set(boxFrame.FrontEdge, 'Visible','on', 'LineStyle','dashdot', 'LineWidth',1);  %defaults: 'off', 'solid', 0.5

As with the Ruler.Axle objects (see last week’s article), we can customize the Vertex points and colors to achieve very colorful effects (anyone say psychedelic?)

GridHandle

In HG2, MathWorks have dramatically improved the appearance of the grid-lines, making them a much lighter, less-obtrusive gray color. Even more importantly, we now have fine-grained control over the grid lines, via the axes’ hidden XGridHandle, YGridHandle and ZGridHandle properties. These return an empty handle when the grid is not shown, and a matlab.graphics.axis.decorator.SimpleGrid class object when the relevant grid-lines are displayed.

>> grid on
>> xgrid = get(gca,'XGridHandle');  % or: hAxes.XGridHandle
>> get(xgrid)
           BackMajorEdge: [1x1 LineStrip]
           BackMinorEdge: [1x1 LineStrip]
                Children: []
                   Color: [0.15 0.15 0.15]
      FirstCrossoverAxis: 0
     FirstCrossoverValue: 0
          FrontMajorEdge: [1x1 LineStrip]
          FrontMinorEdge: [1x1 LineStrip]
           GridLineStyle: '-'
        HandleVisibility: 'off'
               LineWidth: 0.5
              MajorMinor: 'major'
               MajorTick: [-10 -8 -6 -4 -2 0 2 4 6 8 10]
              MinorColor: [0.1 0.1 0.1]
      MinorGridLineStyle: ':'
          MinorLineWidth: 0.5
               MinorTick: []
                  Parent: [1x1 DecorationContainer]
    SecondCrossoverValue: 0
                 Visible: 'on'

As before, we can customize the grid line’s LineWidth, GridLineStyle, and Color. MajorMinor can accept ‘major’ (default), ‘minor’, or ‘majorandminor’, which is pretty intuitive.

customized HG2 axes X-grid
customized HG2 axes X-grid

set(xgrid,'Color','r', 'GridLineStyle',':', 'LineWidth',1.5, 'MajorMinor','majorandminor');

To control the tick lines in 3D plot we can set BackMajorEdge, BackMinorEdge, FrontMajorEdge and FrontMinorEdge in the same way as we did for the BoxFrame. By default only the back-edges are visible. If you wish to also display the front edges, then set the front edge’s Visible to ‘on’ and don’t forget to modify its VertexData to different values than the back edge’s VertexData. As before, colorful effects can be achieved in the grid-lines by customizing the edge objects’ properties:

>> xgrid.BackMajorEdge.get
          AlignVertexCenters: 'on'
             AmbientStrength: 0.3
                ColorBinding: 'object'
                   ColorData: [4x1 uint8]
                   ColorType: 'truecolor'
             DiffuseStrength: 0.6
            HandleVisibility: 'off'
                     HitTest: 'off'
                       Layer: 'back'
                   LineStyle: 'dotted'
                   LineWidth: 1.5
               NormalBinding: 'none'
                  NormalData: []
                      Parent: [1x1 SimpleGrid]
               PickableParts: 'visible'
    SpecularColorReflectance: 1
            SpecularExponent: 10
            SpecularStrength: 0.9
                   StripData: [1 3 5 7 9 11]
                     Texture: []
                  VertexData: [3x10 single]
               VertexIndices: []
                     Visible: 'on'
       WideLineRenderingHint: 'software'

A note about performance

MATLAB HG2, on R2014b, relies on advanced OpenGL hardware features much more than earlier releases. When Matlab detects an incompatible display driver, it issues a warning and reverts to using the much slower software implementation [6]. It is advisable to update the display driver to the very latest version, since this often solves such incompatibilities.
Some computer vendors use custom OEM drivers and their latest version might still be incompatible. For example, on my Lenovo E530 laptop, the latest Intel HG Graphics 4000 driver (v.9.15) was still incompatible; although the system told me that I have the very latest driver installed. I downloaded the latest generic driver (v.10.18) from Intel’s website and this fixed the issue: HG2 now uses hardware-accelerated OpenGL on my laptop, which is much faster. It may not be as 100% compatible with my laptop as the custom OEM version, but so far it appears to work ok and importantly Matlab graphics now work much better. I can always roll-back the driver to the OEM driver if I see a problem with the generic driver.
Next week I will continue my series on Matlab axes customizations, by describing Backdrop, WarpToFill and a few other aspects. Stay tuned!

Categories: Handle graphics, Low risk of breaking in future versions, Stock Matlab function, Undocumented feature


21 Comments (Open | Close)

21 Comments To "Customizing axes part 2"

#1 Comment By Tobias Gram On October 10, 2014 @ 03:15

Hi, how can I change the grid-linewidth? It seems too prominent.

#2 Comment By Yair Altman On October 10, 2014 @ 03:22

@Tobias – You can customize the grid via its handle. For example:

xgrid = get(gca,'XGridHandle');
xgrid.LineWidth = 3;  % default=0.5
xgrid.GridLineStyle = ':';  % default='-'

#3 Comment By Tobias Gram On October 10, 2014 @ 03:44

Thanks, but it seams like 0.5 is minimum. So it will not help me with the problem.

#4 Comment By Yair Altman On October 10, 2014 @ 03:48

Yes, but setting GridLineStyle from ‘-‘ to ‘:’ *will* help…

You can also modify the grid colors to a lighter shade of gray.

#5 Comment By Brad Stiritz On October 15, 2014 @ 19:49

Hi Yair, thanks for the very informative HG2 series.

>MATLAB HG2, on R2014b, relies on advanced OpenGL hardware features..

For convenient reference: it looks like OpenGL 3.0 is the minimum version needed to take full advantage of HG2.

[13]

#6 Comment By Ralf Hielscher On October 16, 2014 @ 04:31

Hi Yair,

thanks for your comments. One thing that drives me around with HG2 is the fact that colorbar is not an axis anymore. As a consequence we can not do anymore

h = colorbar
get(h,'tightInset')

to compute the actual size of the colorbar. Also

set(gcf,'DefaultColorBarCreateFcn',@doSomething)

does not work – Formerly, you could get informed about each newly created axis.

Ralf.

#7 Pingback By Customizing axes part 3 – Backdrop | Undocumented Matlab On October 22, 2014 @ 23:40

[…] In the past two weeks I explained how HG2 (in R2014b) enables us to customize the axes rulers, baselines, box and grid-lines in ways that were previously impossible in HG1 (R2014a or earlier). […]

#8 Comment By gang On November 12, 2014 @ 13:40

Hi,

Thanks for good info.
I have a question about the axis baseline.
Is it possible to change the position of baseline (from zero to say 1.6)?
And if so, is it possible to have multiple baselines?

Thanks a lot.
Gang

#9 Comment By Yair Altman On November 17, 2014 @ 10:28

@Gang – there’s a BaseValue property (value=0), but changing it apparently has no effect (at least in R2014b). Maybe this will be fixed in future Matlab releases.

Re multiple baselines, you can create multiple Baseline objects like this, but unfortunately it doesn’t work (no visible effect) – maybe I did something wrong or maybe it’s blocked in some way. Feel free to experiment and let us all know if you discover anything useful:

hNewBaseline = matlab.graphics.axis.decorator.Baseline('BaseValue',3, 'Parent',gca, 'Axis',1, 'Visible','on')

#10 Comment By Mark On March 20, 2015 @ 09:42

I’m finding that the minimum line width for HG2 export is 1, or 0.5. This looks like a bug.

The following code incorrectly produces PDFs with axis lines 1.0 pts wide:

figH = figure;
plot([0,1], [0,1], 'k');
set(gca, 'LineWidth', 0.25);
print(gcf, '-dpdf', 'test.pdf')

Using the HG2 properties does not work either: axH.XRuler.Axle.LineWidth = 0.1

hgexport and print both show the bug. It happens with svg, pdf, and epsc files. (Be careful with hgexport – it embeds a preview in the eps file that looks correct, but the eps linewidths are wrong, as you can see by embedding in Illustrator or Inkscape).

I’ll report this to the Mathworks but perhaps this saves time for others.

p.s. Yair – thanks for your work on export_fig on github. Glad you picked it up. It’s a workaround for this problem but not a direct substitute, as I want to specify print/paper sizes and not copy what’s onscreen.

#11 Comment By Yair Altman On March 21, 2015 @ 10:13

@Mark – indeed, an internal bug in Matlab causes the minimal line width to be apparently 0.75. The export_fig utility works-around this bug and exports a file (EPS/PDF) having the correct line-width. See [14].

For anyone interested @TMW, this is case #01249115 that I reported on Feb 24. Apparently, LineWidths<0.75 use EPS's default line width, rather than computing the actual value. This affects regular plot lines as well as axes Ruler Axles and grid lines (that have LineWidth=0.5 by default).

#12 Comment By W.T. Door On April 23, 2015 @ 13:29

Yair —

Just wanted to add a comment to let you know that this post was extremely helpful; I was trying to figure out a way to help highlight some differences between surface plots and modifying the Z-axis gridlines worked perfectly. FWIW, I bought your “Undocumented Matlab” book a couple of years ago and it has proved useful time and again — thanks for both the book and the blog.

Regards,
WT

#13 Comment By Fred Vanner On August 20, 2015 @ 01:48

I’m having problems with XGridHandle (etc.) in scripts / functions (I’ve had no problems from the command line). Example:

x=linspace(-1,1);
fx=x.^3;
pfx=plot(x,fx);
grid on;
ax=gca;
xgh=ax.XGridHandle;
xgh.BackMajorEdge.ColorData=cast([0; 20; 20; 200],'uint8');

Running this script (R2014b, 32 bit) I get:
“No appropriate method, property, or field BackMajorEdge for class matlab.graphics.GraphicsPlaceholder.”
If I put a breakpoint after the “grid on” command, and continue from the breakpoint, I get no error (and the grid change works).
This would be really useful if I could persuade it to work reliably. Any ideas?

#14 Comment By Yair Altman On August 20, 2015 @ 02:51

I suggest that you add a call to drawnow; pause(0.1); after the grid creation and before requesting XGridHandle:

x=linspace(-1,1);
fx=x.^3;
pfx=plot(x,fx);
grid on;
ax=gca;
drawnow; pause(0.1);
xgh=ax.XGridHandle;
xgh.BackMajorEdge.ColorData=cast([0; 20; 20; 200],'uint8');

#15 Comment By Fred Vanner On August 20, 2015 @ 02:57

Thanks! That works like a dream! (Why?)

#16 Comment By Yair Altman On August 20, 2015 @ 03:00

Because of the [15].
Also read this: [16]

#17 Comment By stochos On August 21, 2017 @ 00:32

It doesn’t appear that the BoxFrame property is part of Matlab anymore.
Please confirm.

#18 Comment By Yair Altman On August 21, 2017 @ 00:58

The BoxFrame property of an axes handle still exists as of R2017a. It’s hidden, but fully accessible.

#19 Comment By stochos On August 23, 2017 @ 20:29

Many thanks sir.

Please do reveal on how to unhide so that I can access it.

#20 Comment By stochos On August 23, 2017 @ 20:41

Looking at your site, I’ve found the following links.
[17]
[18]

Thanks for your excellent site.

#21 Comment By Tiago Dias On January 11, 2018 @ 18:12

Hello,

I was wondering if is possible just to change the width of the Square of the plot.

Using the BoxFrame i manage to change the width of the square and the grid, but I only want to change the Axes of X and Y bottom and top, left and right.

I found this online :

    hold on
    xl = xlim;
    yl = ylim;
    plot(xl,ones(1,2)*yl(1), '-k', ones(1,2)*xl(1), yl, '-k', 'LineWidth',2); % Left  & Lower Axes
    plot(xl,ones(1,2)*yl(2), '-k', ones(1,2)*xl(2), yl, '-k', 'LineWidth',2); % Right & Upper Axes    
    hold off

but since I have a plot(datatime,variableX) before, is send me an error message because I have datetime data, since datetime is 01/01/2016 00:00:00 etc

Best Regards,
Tiago


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/customizing-axes-part-2

URLs in this post:

[1] explained: http://undocumentedmatlab.com/blog/customizing-axes-rulers

[2] Baseline: http://undocumentedmatlab.com/blog/customizing-axes-part-2#Baseline

[3] BoxFrame: http://undocumentedmatlab.com/blog/customizing-axes-part-2#BoxFrame

[4] GridHandle: http://undocumentedmatlab.com/blog/customizing-axes-part-2#GridHandle

[5] *LimInclude properties: http://undocumentedmatlab.com/blog/plot-liminclude-properties

[6] reverts to using the much slower software implementation: http://www.mathworks.com/help/matlab/creating_plots/resolving-low-level-graphics-issues.html

[7] Customizing axes rulers : https://undocumentedmatlab.com/articles/customizing-axes-rulers

[8] Customizing axes part 4 – additional properties : https://undocumentedmatlab.com/articles/customizing-axes-part-4-additional-properties

[9] Customizing axes part 5 – origin crossover and labels : https://undocumentedmatlab.com/articles/customizing-axes-part-5-origin-crossover-and-labels

[10] Customizing axes part 3 – Backdrop : https://undocumentedmatlab.com/articles/customizing-axes-part-3-backdrop

[11] Customizing axes tick labels : https://undocumentedmatlab.com/articles/customizing-axes-tick-labels

[12] Determining axes zoom state : https://undocumentedmatlab.com/articles/determining-axes-zoom-state

[13] : http://www.mathworks.com/help/matlab/creating_plots/system-requirements-for-matlab-graphics.html

[14] : https://github.com/altmany/export_fig/issues/31

[15] : https://undocumentedmatlab.com/blog/matlab-and-the-event-dispatch-thread-edt

[16] : https://undocumentedmatlab.com/blog/solving-a-matlab-hang-problem

[17] : https://undocumentedmatlab.com/blog/uiinspect

[18] : https://undocumentedmatlab.com/blog/getundoc-get-undocumented-object-properties

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.