How to plot subset of X-axis names on bar plot?

6 views (last 30 days)
Andrew Gemer
Andrew Gemer on 11 Jan 2022
Commented: Andrew Gemer on 14 Jan 2022
Hello, I've run up against a problem that I can't seem to solve and need some help. Basically, I pull in 20 beer names (text strings) from an XLS, and want to create a bar plot of the first 10 of them. I can get it to plot the bars (plotData) for a subset, but every time, the bar plot contains all 20 beer names (plotNames), rather than the subset (10). I've even created a new array (plotNamesD), which contains only 10 beer name strings, but when I use 'bar' to plot it all 20 beer name strings are still plotted on the X-axis. Note that the reason that I loop through keywords is that I eventually want to apply this to other categories as well. Here is my example code:
clc
clear all
close all
rawData = {'Beer1','Draft Beer',NaN,NaN,NaN,928;...
'Beer2','Draft Beer',NaN,NaN,NaN,112;...
'Beer3','Draft Beer',NaN,NaN,NaN,55;...
'Beer4','Draft Beer',NaN,NaN,NaN,697;...
'Beer5','Draft Beer',NaN,NaN,NaN,256;...
'Beer6','Draft Beer',NaN,NaN,NaN,8;...
'Beer7','Draft Beer',NaN,NaN,NaN,430;...
'Beer8','Draft Beer',NaN,NaN,NaN,72;...
'Beer9','Draft Beer',NaN,NaN,NaN,76;...
'Beer10','Draft Beer',NaN,NaN,NaN,346;...
'Beer11','Draft Beer',NaN,NaN,NaN,86;...
'Beer12','Draft Beer',NaN,NaN,NaN,345;...
'Beer13','Draft Beer',NaN,NaN,NaN,4;...
'Beer14','Draft Beer',NaN,NaN,NaN,28;...
'Beer15','Draft Beer',NaN,NaN,NaN,98;...
'Beer16','Draft Beer',NaN,NaN,NaN,92;...
'Beer17','Draft Beer',NaN,NaN,NaN,94;...
'Beer18','Draft Beer',NaN,NaN,NaN,154;...
'Beer19','Draft Beer',NaN,NaN,NaN,367;...
'Beer20','Draft Beer',NaN,NaN,NaN,637};
% Determine number of rows
nRows = size( rawData, 1 );
% - Define category keywords
keywords = {'Appetizers',...
'Bottled Beer',...
'Draft Beer',...
'Lunch Specials',...
'Wine'} ;
% - Prealloc cell arrays for storing the output of find in column.
nKeyword = numel( keywords ) ;
keywordPos = cell( nRows, nKeyword ) ;
% - Iterate through elements of keywords and find in all data rows.
for kId = 1 : nKeyword
keywordPos(:,kId) = strfind( rawData(:,2), keywords{kId} ).' ;
end
% - Convert to arrays of logicals flagging "found at least one", which
% translates into "check not empty".
hasKeyword = ~cellfun( @isempty, keywordPos ) ;
numBeers = 10; % Number of top selling beers to plot
for kId = 1 : nKeyword
if strcmp(keywords{kId}, 'Draft Beer')
f=figure('WindowState','maximized');
plotData = cell2mat(rawData(hasKeyword(:,kId)==1,6));
% Sort from highest seller to lowest - may not be necessary
% bar(sort(plotData(:,1),'descend'));
plotNames = categorical(rawData(hasKeyword(:,kId)==1,1));
plotNames = reordercats(plotNames,rawData(hasKeyword(:,kId)==1,1));
% Attempt to reduce the size of the plotNames array to
% address why 'bar' can only plot the full array of names
plotNamesD = plotNames(1:numBeers);
plotDataD = plotData(1:numBeers);
bar(plotNamesD,plotDataD);
% Plot numbers at top of bar
text(1:length(plotData),plotData,num2str(plotData),'vert','bottom','horiz','center');
box off
% Plot categorgy name as the title of the plot
title(keywords(kId));
grid on;
end
end
And here is the current output:
I want to truncate this bar plot after "Beer10", but I'm struggling to do so even though the lengths of both plotDataD and plotNamesD is 10. As a side note, I also want to sort in descending order and make sure the beer names are correct and stay with their counts, but I haven't tackled that yet. Any help you can offer would be greatly appreciated!

Accepted Answer

VBBV
VBBV on 12 Jan 2022
Edited: VBBV on 12 Jan 2022
plotNamesD = plotNames(1:kId);% use the for loop index
plotDataD = plotData(1:kId);
bar(plotNamesD,plotDataD);
hold on
Use the for loop index if you want to truncate the bar plot.
  6 Comments
Andrew Gemer
Andrew Gemer on 14 Jan 2022
Ok awesome! So you definitely caught at least one problem with my code (using plotData instead of plotDataD in the text line), so I'm going to mark this questions "solved" so that you get credit for it!
However, the second comment, changing the categorical plotNamesD to double doesn't meet my needs - in practice, there are like 500+ beer names, so I want the actual beer name (for example, the string 'Coors Light') to be displayed rather than just a number as in your example. So if I do not change the names to doubles, I still have the problem where all 20 beer names are plotted, rather than just the 10 I wanted. See below screenshot for an example:

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!