- Undocumented Matlab - https://undocumentedmatlab.com -
Customizing histogram plots
Posted By Yair Altman On January 17, 2018 | 2 Comments
Earlier today, I was given the task of displaying a histogram plot of a list of values. In today’s post, I will walk through a few customizations that can be done to bar plots and histograms in order to achieve the desired results.
We start by binning the raw data into pre-selected bins. This can easily be done using the builtin histc (deprecated) or histcounts functions. We can then use the bar function [1] to plot the results:
[binCounts, binEdges] = histcounts(data);
hBars = bar(hAxes, binEdges(1:end-1), binCounts);
hAxes = hBar.Parent;
xtickformat(hAxes, '%g%%');
title(hAxes, 'Distribution of total returns (monthly %)');
set(hAxes, 'FontSize',8, 'Box','off')
set(hAxes, 'LooseInset',[0,0,0,0]); % default = [.13,.11,.095,.075]
hAxes.XRuler.TickLabelGapOffset = -2; % default = +2
hAxes.XTick(end+1) = hAxes.XTick(end) + 1; % extra tick label on the right
labels = hAxes.XTickLabels; % preserve tick labels for later use below
hAxes.XTick = hAxes.XTick - 0.5; % move tick labels 1/2 bin leftward
hAxes.XTickLabel = labels; % restore pre-saved tick labels
hAxes.XLim = hAxes.XLim - 0.5; % ...and align the XLim
'histc'
flag, in order to display the bars in histogram mode. The problem in histogram mode is that while the labels are now placed correctly, the bars touch each other – I personally find distinct bars that are separated by a small gap easier to understand.
hBars = bar(..., 'histc');
% [snip] - same customizations to hAxes as done above
'hist'
or 'histc'
(i.e. histogram mode) results in a Patch
(not Bar
) object, and patches do not have a BarWidth property. However, we can modify the resulting patch vertices in order to achieve the same effect:
% Modify the patch vertices (5 vertices per bar, row-based)
hBars.Vertices(:,1) = hBars.Vertices(:,1) + 0.1;
hBars.Vertices(4:5:end,1) = hBars.Vertices(4:5:end,1) - 0.2;
hBars.Vertices(5:5:end,1) = hBars.Vertices(5:5:end,1) - 0.2;
% Align the bars & labels at the center of the axes
hAxes.XLim = hAxes.XLim + 0.5;
This now looks the same as option #1 above, except that the top-level handle is a Patch
(not Bar
) object. For various additional customizations, either Patch
or Bar
might be preferable, so you have a choice.
Quadrilateral
objects (a close relative of Patch
). The solution here is very similar to option #2 above, but we need to dig a bit harder to modify the patch faces, since their vertices is not exposed as a public property of the Histogram
object. To modify the vertices, we first get the private Face property (explanation [6]), and then modify its vertices, keeping in mind that in this specific case the bars have 4 vertices per bar and a different vertices matrix orientation:
hBars = histogram(data, 'FaceAlpha',1.0, 'EdgeColor','none');
% [snip] - same customizations to hAxes as done above
% Get access to *ALL* the object's properties
oldWarn = warning('off','MATLAB:structOnObject');
warning off MATLAB:hg:EraseModeIgnored
hBarsStruct = struct(hBars);
warning(oldWarn);
% Modify the patch vertices (4 vertices per bar, column-based)
drawnow; % this is important, won't work without this!
hFace = hBarsStruct.Face; % a Quadrilateral object (matlab.graphics.primitive.world.Quadrilateral)
hFace.VertexData(1,:) = hFace.VertexData(1,:) + 0.1;
hFace.VertexData(1,3:4:end) = hFace.VertexData(1,3:4:end) - 0.2;
hFace.VertexData(1,4:4:end) = hFace.VertexData(1,4:4:end) - 0.2;
In conclusion, there are many different ways to improve the appearance of charts in Matlab. Even if at first glance it may seem that some visualization function does not have the requested customization property or feature, a little digging will often find either a relevant undocumented property, or an internal object whose properties could be modified. If you need assistance with customizing your charts for improved functionality and appearance, then consider contacting me for a consulting session [7].
Categories: Handle graphics, Medium risk of breaking in future versions, Stock Matlab function, Undocumented feature
Article printed from Undocumented Matlab: https://undocumentedmatlab.com
URL to article: https://undocumentedmatlab.com/articles/customizing-histogram-plots
URLs in this post:
[1] bar function: https://www.mathworks.com/help/matlab/ref/bar.html
[2] see this post: http://undocumentedmatlab.com/blog/setting-axes-tick-labels-format
[3] LooseInset property: http://undocumentedmatlab.com/blog/axes-looseinset-property
[4] XAxis property: https://www.mathworks.com/help/matlab/ref/matlab.graphics.axis.axes-properties.html#prop_XAxis
[5] histogram function: https://www.mathworks.com/help/matlab/ref/histogram.html
[6] explanation: http://undocumentedmatlab.com/blog/accessing-private-object-properties
[7] consulting session: http://undocumentedmatlab.com/consulting
[8] Customizing contour plots : https://undocumentedmatlab.com/articles/customizing-contour-plots
[9] Customizing contour plots part 2 : https://undocumentedmatlab.com/articles/customizing-contour-plots-part2
[10] Customizing contour plots part 2 : https://undocumentedmatlab.com/articles/customizing-contour-plots-part-2
[11] Customizing axes tick labels : https://undocumentedmatlab.com/articles/customizing-axes-tick-labels
[12] Customizing axes part 3 – Backdrop : https://undocumentedmatlab.com/articles/customizing-axes-part-3-backdrop
[13] Customizing axes part 4 – additional properties : https://undocumentedmatlab.com/articles/customizing-axes-part-4-additional-properties
[14] : https://www.eoas.ubc.ca/~rich/map.html
Click here to print.
Copyright © Yair Altman - Undocumented Matlab. All rights reserved.
2 Comments To "Customizing histogram plots"
#1 Comment By chengji chen On February 13, 2023 @ 04:45
Hi, I have tried the method, but it didn’t work.
I plot figure by m_map toolbox, the xticklabel will add to the yticklabel at the left-down corner, so I want to move down the xticklabel, but it didn’t work.
Is there any other way to do it?
#2 Comment By Yair Altman On February 13, 2023 @ 11:04
m_map is a mapping tool, not even created by MathWorks and not part of the basic Matlab system. I have no idea why you think that the customizations to the builtin bar function in this article should also apply to m_map.
If you need assistance with m_map, contact its developer ( [14])