Add dots at peak of bars in a bar graph and draw a line between them?
    17 views (last 30 days)
  
       Show older comments
    
Hi all,
I originally plotted data in a bar graph with brain regions along the x-axis and some measure along the y-axis. Each region has 2 data points, one for each condition. I have since realized that a bar graph is not the best way to visualize said data; instead, I want to draw dots at the peak of each bar and a line connecting the two dots of a single region (one for each condition). From the attached figure, that would mean that at RH PHC2 for example, there would be a blue dot at the peak of the left/blue column and an orange dot at the peak of the right/orange column with a line connecting the two dots. 
I assume that the easiest way to accomplish this would be to add the dots and lines to the current graph, and then make the bars transparent resulting in a pseudo-dot plot. I don't know how to do this however. I've attached the code of my figures thus far in hopes that I can receive some assistance. 
If it is easier to start from scratch, I'm happy to do that too, but would appreciate getting pointed in the right direction!
Thanks,
George
>> BetRSF
BetRSF =
   13.0000         0  277.9367  347.5332    6.0000    1.0000
   48.0000         0  245.8306  315.4521   24.0000    2.0000
   26.0000    0.0168  133.7187  141.7139   12.0000    3.0000
   49.0000         0  109.6015  133.0241   25.0000    4.0000
   46.0000         0   85.4435  101.6307   22.0000    5.0000
   36.0000         0   69.4742   74.8517   17.0000    6.0000
   30.0000         0   63.1806   68.0751   14.0000    7.0000
>> RegRSF
RegRSF = 
  7×1 categorical array
     RH PHC2 
     RH vPCu 
     RH TO1/MT 
     RH vTO 
     RH SEF 
     RH IPS3 
     RH V7/IPS0 
[BRSFrow, BRSFcol]=size(BetRSF); % need rows for 'for' loop
figure(15)   
%     subplot(3,2,4)
        bar(RegRSF,BetRSF(:,3:4))
        ylim([0 370]);
        title('Right - Saccade Greater');
        for i=1:BRSFrow
            text(i-.05, BetRSF(i,4)+10, '*','FontSize', 20);
        end

0 Comments
Accepted Answer
  Adam Danz
    
      
 on 29 Jan 2021
        
      Edited: Adam Danz
    
      
 on 29 Jan 2021
  
      Working with categorical axis rulers is tricky because you can't use simple arithmetic to get the bar centers.  The demo below compares the bar plot to a line plot.  You can't use categorical x values if you want two markers with slight separation per category. This solution uses a numeric x axis ruler and uses the category names as XTickLabels.  If you want he categories to be in the same order as the bar plot, you have to rearrange the data to match the categorical order which this solution also demonstrates. Lastly, the separation between groups is set to 0.1 which is arbitrary but affects the slope of each line segment.
BetRSF =[
    13.0000         0  277.9367  347.5332    6.0000    1.0000
    48.0000         0  245.8306  315.4521   24.0000    2.0000
    26.0000    0.0168  133.7187  141.7139   12.0000    3.0000
    49.0000         0  109.6015  133.0241   25.0000    4.0000
    46.0000         0   85.4435  101.6307   22.0000    5.0000
    36.0000         0   69.4742   74.8517   17.0000    6.0000
    30.0000         0   63.1806   68.0751   14.0000    7.0000];
RegRSF = categorical([
    "RH PHC2"
    "RH vPCu"
    "RH TO1/MT"
    "RH vTO"
    "RH SEF"
    "RH IPS3"
    "RH V7/IPS0"]);
figure()
ax(1) = subplot(2,1,1);
h = bar(ax(1), RegRSF,BetRSF(:,3:4));
grid(ax(1),'on')
ax(2) = subplot(2,1,2);
grid(ax(2),'on')
hold(ax(2),'on')
box(ax(2),'on')
x = (1:numel(RegRSF)) + 0.1*[-1;1]; % set inter-group distance
y = BetRSF(:,3:4)';
% Reorder y to same order as barplot
[~, idx] = ismember(categories(RegRSF),cellstr(RegRSF));
y = y(:,idx);
% Plot lines and endpoints
lh = plot(ax(2), x,y, 'k-','LineWidth',2);
plot(x(1,:), y(1,:), 'ko','MarkerFaceColor','b')
plot(x(2,:), y(2,:), 'ko','MarkerFaceColor','r')
xlim(ax(2), [.5, numel(RegRSF)+.5])
ax(2).XTick = 1:numel(RegRSF);
ax(2).XTickLabel = categories(RegRSF);
ax(2).XTickLabelRotation = 25;
12 Comments
  Adam Danz
    
      
 on 18 Mar 2021
				It should be
axis(ax(2), 'padded')
To narrow the spaces between points, you can change the axis size
ax(2).Position(3) = ax(2).Position(3).*.75; % 75% the width
or the figure
fig.Position(3) = fig.Position(3)*.75;  % 75% the fig width
More Answers (1)
  Sumedh Deshpande
    
 on 29 Jan 2021
        Hi George, 
I am assuming are using R2020a or higher version of MATLAB.
Here is one way of getting the graph with lines, just comment the line hold on and hold off to get just the line graph
[BRSFrow, BRSFcol]=size(BetRSF); % need rows for 'for' loop
figure(15)
%     subplot(3,2,4)
bar(RegRSF,BetRSF(:,3:4))
ylim([0 370]);
title('Right - Saccade Greater');
forLine = [];
for i=1:BRSFrow
    text(i-.05, BetRSF(i,4)+10, '*','FontSize', 20);
    forLine = [forLine  BetRSF(i,4)+10]; % to store the locations of * in a an array
end
hold on; % to keep the old graph 
plot(forLine) % plot the lone graph
hold off;
0 Comments
See Also
Categories
				Find more on Data Distribution Plots in Help Center and File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


