How to get (x,y) coordinates of a categorical bar graph?

24 views (last 30 days)
Hello, I am using bar(a,b) to plot a bar graph, with the x-axis containg categorical data (a is a categorical array), and the y-axis containg numerical data (b is a vector of numerical values).
If I want to plot additional lines on this figure, or add text using text() function, I need to reference the (x,y) position on the bar graph. However, I'm limited in which x-positions I choose, since vector a only references x positions at the center of each category. Is there a way to reference numerical x positions?
Example:
In the image below, I know how to add text near the blue circle (which can be referenced by the first category along the x-axis and a y-value of -20), but don't know how to add text near the red circle (which can be referenced by a y-value of -20, but no x-value).

Accepted Answer

dpb
dpb on 27 Oct 2020
To do the desired you've got two choices -- when you use a categorical variable, TMW has created a specific axes that is not numeric--
>> hAx=gca;
>> hAx.YAxis
ans =
NumericRuler with properties:
Limits: [-40.00 40.00]
Scale: 'linear'
Exponent: 0
TickValues: [-40.00 -30.00 -20.00 -10.00 0 10.00 20.00 30.00 40.00]
TickLabelFormat: '%g'
Show all properties
>> hAx.XAxis
ans =
CategoricalRuler with properties:
Categories: {3×1 cell}
Limits: [a c]
TickValues: [a b c]
Show all properties
>>
So, there are no values for intermediary and no numeric values along the x axis...that you already know; just to illustrate the difference is fundamental to the type of the axes object, not just a numeric axis being camoflauged to look like a categorical as used to be the case. I'm not sure just which release introduced the change...
So, you either
  1. use a numeric variable for the original plot and then xticklabel to label the ticks at positions 1:3 or
  2. Add a second numeric axis on top and put the other stuff on it.
The latter would be something like
hAx=gca; % get handle to first axes
hold on % don't wipe out
hAx(2)=axes('position',hAx(1).Position,'Color','none'); % create new axes on to original
set(hAx(2),{'XTick';'YTick'},{[],[]}, ...
{'XLim','YLim'},{hAx(1).XAxis.NumericLimits,hAx(1).YLim}) % turn off ticks, scale to match
and then plot() or text() into hAx(2)
The categorical axes numerical range is obtained from the hidden 'NumericalLimits' property of the XAxis categorical object.
Unfortunately one has to know about Yair Altman's undocumented properties routine to be able to easily poke around and find out such information.
  2 Comments
Vincent
Vincent on 16 Feb 2021
I tried exactly this approach to get a BoxChart object and Line object into one figure. But the Line object covers the BoxChart, even though I have set the second axis' color to 'none'.
Any suggestions what could be wrong?
figure
ax1 = gca;
box = boxchart(groups.Threshold,groups.Value,'GroupByColor',groups.System,'Parent',ax1,'MarkerStyle','o','BoxWidth',0.5);
ax2 = axes('Position',ax1.position,'Color','none');
p = plot([0.1 0.4],[0.9 0.3],'Parent',ax2); %,'MarkerEdgeColor','r','LineWidth',2)
ax2.XLim = [0 1];
ax2.YLim = [0 1];
Vincent
Vincent on 16 Feb 2021
I could answer the question myself... If I set the axis' color to 'none' once again after plotting the line, it works. Don't know why though...

Sign in to comment.

More Answers (0)

Categories

Find more on Labels and Annotations in Help Center and File Exchange

Tags

Products


Release

R2017a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!